Create ViewHelper in Symfony 2 - symfony-2.1

How to create a ViewHelper in Symfony 2. I read whole the documentation but it doesn't describe any term like that. It just has autoloading and service.
http://symfony.com/doc/current/cookbook/index.html

You just have to create a class that implements your helper function and extends
Symfony\Component\Templating\Helper\Helper
like this:
namespace Acme\Foo\Helper;
use Symfony\Component\Templating\Helper\Helper;
class MyViewHelper extends Helper {
public function helpMe() {
// do something
return $value;
}
/**
* #inheritdoc
*/
public function getName() {
return "anyCanonicalServiceName";
}
}
Then you have to promote your helper as a service with a special tag in e.g.
Resources/config/services.yml
services:
your_service_name:
class: Acme\Foo\Helper\MyViewHelper
# the tag alias "myViewHelper" is later used in the view to access your service
tags:
- { name: templating.helper, alias: myViewHelper }
Now you can access the helper in a view like this:
echo $view['myViewHelper']->helpMe();

Related

Class Illuminate\Bus\Dispatcher contains 3 abstract methods and must therefore be declared abstract or implement the remaining methods

I am trying to use Laravel Jobs, and that worked for few times but now I am getting this error.
Class Illuminate\Bus\Dispatcher contains 3 abstract methods and must therefore be declared abstract or implement the remaining methods
"message": "Class Illuminate\Bus\Dispatcher contains 3 abstract methods and must therefore be declared abstract or implement the remaining methods (Illuminate\Contracts\Bus\QueueingDispatcher::findBatch, Illuminate\Contracts\Bus\QueueingDispatcher::batch, Illuminate\Contracts\Bus\Dispatcher::dispatchSync)",
"exception": "Symfony\Component\ErrorHandler\Error\FatalError",
"file": "D:\xampp8\htdocs\sa-new\laravel-develop\vendor\laravel\framework\src\Illuminate\Bus\Dispatcher.php",
"line": 13,
My controller code looks like this
namespace App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Response;
use App\Model\BccMapping;
use App\Jobs\ProcessUnmappedRequests;
public function processUnmappedRequests(Request $request){
ProcessUnmappedRequests::dispatch('3',$request);
}
While my Job's code looks like this.
<?php
namespace App\Jobs;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Model\BccMapping;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessUnmappedRequests implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $request;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($id, $request)
{
$this->siteId = $request->get('siteId');
$this->mappingId = $request->get('mappingId');
$this->email = $request->get('originEmail');
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$unmappedRequests = DB::table('bcc')->where("EmailFrom", trim($this->email))->whereNull('BccMappingId')
->where('Archive',0)->get();
if($unmappedRequests->isNotEmpty()){
$mapping = BccMapping::where('id',$this->mappingId )->first();
if(!$mapping)
return false;
$mappingData = json_decode($mapping->mapping);
$keyword = $mapping->keyword;
foreach ($unmappedRequests as $key=>$bcc){
$bccKeyword = app('App\Http\Controllers\BccToolController')->getDomNodeValue($mappingData->keywordPath->path,$bcc->HTML);
var_dump($bccKeyword);die;
}
}else{
return false;
}
}
}
Currently I am using Laravel 7.0 and PHP 7.4.

Laravel Package development: Facade alias not found

I try to create an alias for a facade in a Laravel 7 package.
On testing I get the message:
Error: Class 'MemberRequest' not found
Test:
/** #test */
public function a_member_request_can_be_created()
{
$this->assertDatabaseMissing('member_requests', ['created_at' => Date::now()]);
\MemberRequest::create(new CreateMemberRequestRequest(['email_address' => $this->email_address]));
$this->assertDatabaseHas('member_requests', ['created_at' => Date::now()]);
}
I did the following steps:
create a facade (extending the facade class from Laravel Illuminate
Register it in the service provider
add the alias to the config file
add the alias to the composer.json file
Create a Facade:
namespace martijn\UMS\Repositories\Facades;
use Illuminate\Support\Facades\Facade;
class MemberRequestRepositoryFacade extends Facade
{
public static function getFacadeAccessor()
{
return 'MemberRequest';
}
}
Register in serviceProvider:
namespace martijn\UMS\Providers;
use Illuminate\Support\ServiceProvider;
use martijn\UMS\Repositories\MemberRequestRepository;
class UMSBaseServiceProvider extends ServiceProvider
{
public function register()
{
$this->registerFacades();
}
private function registerFacades()
{
// Facades
$this->app->singleton('MemberRequest', function () {
return new MemberRequestRepository();
});
}
}
Add it to a config file:
return [
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'MemberRequest' => \martijn\UMS\Repositories\Facades\MemberRequestRepositoryFacade::class,
]
];
Add it to composer.json:
"aliases": {
"MemberRequest": "martijn\\UMS\\Repositories\\Facades\\MemberRequestRepositoryFacade"
}
I found out that it is done in the boot loader of the service provider like this:
https://laracasts.com/discuss/channels/laravel/dynamic-class-aliases-in-package
In my example it was:
$loader = AliasLoader::getInstance();
$loader->alias('MemberRequest', \martijn\UMS\Repositories\Facades\MemberRequestRepositoryFacade::class);
In your ServiceProvider, try like this:
$this->app->singleton('MemberRequest', function () {
return new MemberRequestRepository;
});

Codeigniter 4 - call method from another controller

How to call "functionA" from "ClassA" in "functionB" inside "ClassB" ?
class Base extends BaseController
{
public function header()
{
echo view('common/header');
echo view('common/header-nav');
}
}
class Example extends BaseController
{
public function myfunction()
// how to call function header from base class
return view('internet/swiatlowod');
}
}
Well there are many ways to do this...
One such way, might be like...
Assume that example.php is the required Frontend so we will need a route to it.
In app\Config\Routes.php we need the entry
$routes->get('/example', 'Example::index');
This lets us use the URL your-site dot com/example
Now we need to decide how we want to use the functions in Base inside Example. So we could do the following...
<?php namespace App\Controllers;
class Example extends BaseController {
protected $base;
/**
* This is the main entry point for this example.
*/
public function index() {
$this->base = new Base(); // Create an instance
$this->myfunction();
}
public function myfunction() {
echo $this->base->header(); // Output from header
echo view('internet/swiatlowod'); // Output from local view
}
}
When and where you use new Base() is up to you, but you need to use before you need it (obviously).
You could do it in a constructor, you could do it in a parent class and extend it so it is common to a group of controllers.
It's up to you.

How can I pass parameter in the laravel excel?

I get tutorial from here : https://laravel-excel.maatwebsite.nl/docs/3.0/export/basics
<?php
...
use App\Exports\ItemsDetailsExport;
class ItemController extends Controller
{
...
public function exportToExcel(ItemsDetailsExport $exporter, $id)
{
//dd($id); I get the result
return $exporter->download('Summary Detail.xlsx');
}
}
My export like this :
<?php
namespace App\Exports;
use App\Repositories\Backend\ItemDetailRepository;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
use Illuminate\Support\Facades\Input;
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
public function __construct(ItemDetailRepository $itemDetailRepository)
{
$this->itemDetailRepository = $itemDetailRepository;
}
public function collection()
{
$test = Input::get('id');
dd('yeah', $test);
}
}
I want to pass id parameter to export file. I try like that, but I don't get the id. The id is null
How can I solve this problem?
For passing data from controller to laravel excel function we can pass and use data like below
For example, we have to pass data year like 2019 we will pass like below
in controller
Excel::download(new UsersExport(2019), 'users.xlsx');
In laravel import file
class UsersExport implements FromCollection {
private $year;
public function __construct(int $year)
{
$this->year = $year;
}
public function collection()
{
return Users::whereYear('created_at', $this->year)->get();
}
}
you can refer all following official documentation link
https://docs.laravel-excel.com/3.1/architecture/objects.html#plain-old-php-object
Unfortunately you can't use normal dependency injection when you have a specific parameter. This is what you can do though:
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
protected $id;
public function __construct(ItemDetailRepository $itemDetailRepository, $id)
{
$this->itemDetailRepository = $itemDetailRepository;
$this->id = $id;
}
public function collection()
{
$test = $this->id;
dd('yeah', $test);
}
}
Now the problem is that the container doesn't know how to resolve $id however there are two ways around this.
Manual passing of $id:
public function exportToExcel($id)
{
$exporter = app()->makeWith(ItemsDetailsExport::class, compact('id'));
return $exporter->download('Summary Detail.xlsx');
}
Route injection:
Define your route as:
Route::get('/path/to/export/{itemExport}', 'ItemController#exportToExcel');
In your RouteServiceProvider.php:
public function boot() {
parent::boot();
//Bindings
Route::bind('itemExport', function ($id) { //itemExport must match the {itemExport} name in the route definition
return app()->makeWith(ItemsDetailsExport::class, compact('id'));
});
}
Then your route method is simplified as:
public function exportToExcel(ItemsDetailsExport $itemExport)
{
//It will be injected based on the parameter you pass to the route
return $itemExport->download('Summary Detail.xlsx');
}

ViewHelper newable/injectable dilemma

I'm trying to design an application following Misko Heverys insights. It's an interesting experiment and a challenge. Currently I'm struggling with my ViewHelper implementation.
The ViewHelper decouples the model from the view. In my implementation it wraps the model and provides the API for the view to use. I'm using PHP, but I hope the implementation is readable for everyone:
class PostViewHelper {
private $postModel;
public function __construct(PostModel $postModel) {
$this->postModel = $postModel;
}
public function title() {
return $this->postModel->getTitle();
}
}
In my template (view) file this could be called like this:
<h1><?php echo $this->post->title(); ?></h1>
So far so good. The problem I have is when I want to attach a filter to the ViewHelpers. I want to have plugins that filter the output of the title() call. The method would become like this:
public function title() {
return $this->filter($this->postModel->getTitle());
}
I need to get observers in there, or an EventHandler, or whatever service (in what I see as a newable, so it needs to be passed in through the stack). How can I do this following the principles of Misko Hevery? I know how I can do this without it. I'm interested in how for I can take it and currently I don't see a solution. ViewHelper could be an injectable too, but then getting the model in there is the problem.
I didn't find the blog post you referenced very interesting or insightful.
What you are describing seems more like a Decorator than anything to do with dependency injection. Dependency injection is how you construct your object graphs, not their state once constructed.
That said, I'd suggest taking your Decorator pattern and running with it.
interface PostInterface
{
public function title();
}
class PostModel implements PostInterface
{
public function title()
{
return $this->title;
}
}
class PostViewHelper implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->post = $post;
}
public function title()
{
return $this->post->title();
}
}
class PostFilter implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->post = $post;
}
public function title()
{
return $this->filter($this->post->title());
}
protected function filter($str)
{
return "FILTERED:$str";
}
}
You'd simply use whatever DI framework you have to build this object graph like so:
$post = new PostFilter(new PostViewHelper($model)));
I often use this approach when building complex nested objects.
One problem you might run into is defining "too many" functions in your PostInterface. It can be a pain to have to implement these in every decorator class. I take advantage of the PHP magic functions to get around this.
interface PostInterface
{
/**
* Minimal interface. This is the accessor
* for the unique ID of this Post.
*/
public function getId();
}
class SomeDecoratedPost implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->_post = $post;
}
public function getId()
{
return $this->_post->getId();
}
/**
* The following magic functions proxy all
* calls back to the decorated Post
*/
public function __call($name, $arguments)
{
return call_user_func_array(array($this->_post, $name), $arguments);
}
public function __get($name)
{
return $this->_post->get($name);
}
public function __set($name, $value)
{
$this->_post->__set($name, $value);
}
public function __isset($name)
{
return $this->_post->__isset($name);
}
public function __unset($name)
{
$this->_post->__unset($name);
}
}
With this type of decorator in use, I can selectively override whatever method I need to provide the decorated functionality. Anything I don't override is passed back to the underlying object. Multiple decorations can occur all while maintaining the interface of the underlying object.

Resources