Laravel 3 - Extending from a controller that extends the Base controller - php

Why do I get a
Class 'Search_Controller' not found
when doing this:
class Snippets_Controller extends Search_Controller {
public $restful = true;
public function get_index()
{
$snippets = Snippet::all();
$categories = Categorie::all();
return View::make('snippet.index')->with(array(
'snippets' => $snippets,
'categories' => $categories,
'active_categorie' => Session::get('active_categorie_id')
)
);
}
The Search Controller:
class Search_Controller extends Base_Controller {
protected static function build_html_for_search_results($search_results)
{
...

You should autoload this in you application start.php folder.
If you open that file, and you search for "Base_Controller", you will see something like this:
Autoloader::map(array(
'Base_Controller' => path('app').'controllers/base.php'
));
The only thing you have to do is add the search controller there:
Autoloader::map(array(
'Base_Controller' => path('app').'controllers/base.php',
'Search_Controller' => path('app').'controllers/search.php'
));
And that should do the trick.
Laravel loads controllers based on the name that's requested, and it doesn't autload any of the controllers, as it would be a waste of time for 90% of the controllers.

Related

is there a possibility to make pagination work for multiple tables within same controller and view

controller code : code for controller works for Employers pagination but unable to work pagination about Stories controller.
public $paginate = [
'Employers' => ['scope' => 'employer'],
'Stories' => ['scope' => 'story']
];
public function index()
{
// Paginate property
$this->loadComponent('Paginator');
// In a controller action
$stories = $this->paginate($this->Stories, ['scope' => 'story']);
$employers = $this->paginate($this->Employers, ['scope' => 'employer']);
pr($stories);
$this->set(compact('employers', 'stories'));
}
Model code: model description stand same for all model as yet but understand that model definition unable to work for stories model but as we progress with model definition about employers table that works absolutely fine.
<?php
// src/Model/Table/EmployersTable.php
namespace App\Model\Table;
use Cake\ORM\Table;
class EmployersTable extends Table
{
public function initialize(array $config): void
{
$this->addBehavior('Timestamp');
}
}
<?php
// src/Model/Entity/Employer.php
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Spk extends Entity
{
protected $_accessible = [
'*' => true,
'id' => false,
'slug' => false,
];
}
<?php
// src/Model/Table/StoriesTable.php
namespace App\Model\Table;
use Cake\ORM\Table;
class StoriesTable extends Table
{
public function initialize(array $config): void
{
$this->addBehavior('Timestamp');
}
}
<?php
// src/Model/Entity/Story.php
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Sty extends Entity
{
protected $_accessible = [
'*' => true,
'id' => false,
'slug' => false,
];
}
Bug i keep looking at as i get through load page action i face that Employers data called but Stories data unable to load. Suggestions are open to view look forward to your answers.
error message:
Undefined property: EmployersController::$Stories in /Applications/MAMP/htdocs/sd/sd/src/Controller/EmployersController.php
Surely it's possible, the feature is explicitly documented. The error has nothing to do with pagination, it simply means that the property that you're trying access ($this->Stories) doesn't exist.
Controllers only have one default model that is being loaded automatically, and that's the model that matches the controller name according to the conventions, so in your EmployersController that's the Employers model. Additional models need to be loaded manually:
$this->loadModel('Stories');
// ...
$stories = $this->paginate($this->Stories, ['scope' => 'story']);
See also
Cookbook > Controllers > Loading Additional Models
No, That is not possible as CakePHP only works for single table with multiple pagination query request to same model. But doesn't not apply to many models.

PHP don't repeat code ( don't repeat yourself )

i am using codeigniter (template) library in codeigniter. I always repeat template library code in every function. will you help me to reduce the code.
public function index(){
//Load View in template file
$this->template->title('Contacts')
->set_layout($this->admin_home_layout)
->set_partial('header', 'admin/admin_share/admin_header')
->set_partial('sidebar', 'admin/admin_share/admin_sidebar')
->set_partial('footer', 'admin/admin_share/admin_footer')
->set_partial('hidenbar', 'admin/admin_share/admin_hidenbar')
->build('admin/admin_home');
}
These 4 lines i am using in every function. how i can use one time in one controller and how to get in function.
->set_partial('header', 'admin/admin_share/admin_header')
->set_partial('sidebar', 'admin/admin_share/admin_sidebar')
->set_partial('footer', 'admin/admin_share/admin_footer')
->set_partial('hidenbar', 'admin/admin_share/admin_hidenbar')
This is how I do it ( applicable for any framework in PHP that has similar way of rendering views):
Suppose that the controllers look like this:
<?php
class AdminController extends BaseController{
public function viewData($id){
// do something
$this->render('something static 1');
$this->render('customview');
$this->render('something static 2');
$this->render('something static 3');
}
}
?>
What I would do is create a base controller to do this rendering tasks ( and more repetitive stuffs):
<?php
class MyBaseController extends BaseController{
protected function renderAll($param){
if(empty($param)){
return false;
}
$this->render('something static 1');
$this->render($param);
$this->render('something static 2');
$this->render('something static 3');
return true;
}
}
?>
Once this is done, I will simply inherit the newly created controller in all my controllers, such as:
<?php
class AdminController extends MyBaseController{
public function viewData($id){
// do something
$this->renderAll('customview');
}
}
?>
You can re-use this in any controller action you want to, just inherit the custom base controller class.
you can set them in the constructor:
public function __construct() {
parent::__construct();
//Do your stuf here
}
Or you could create a function for it:
function set_partials() {
$this->template->set_partial('header', 'admin/admin_share/admin_header')
->set_partial('sidebar', 'admin/admin_share/admin_sidebar')
->set_partial('footer', 'admin/admin_share/admin_footer')
->set_partial('hidenbar', 'admin/admin_share/admin_hidenbar')
}
In this second case, you're index would look like this:
public function index(){
//Load View in template file
$this->template->title('Contacts')
->set_layout($this->admin_home_layout);
$this->set_partials();
$this->template->build('admin/admin_home');
}
i suggest a different logic, just a custom array for your partials like this :
protected $partials = [
'header' => 'admin/admin_share/admin_header',
'sidebar' => 'admin/admin_share/admin_sidebar',
'footer' => 'admin/admin_share/admin_footer',
'hidenbar' => 'admin/admin_share/admin_hidenbar'
];
and use this function to build layout
public function build_layout()
{
$this->template->title('Contacts')->set_layout($this->admin_home_layout);
foreach($this->partials as $k => $partial){
$this->template->set_partial($k,$partial);
}
$this->template->build('admin/admin_home');
}

View helper plugin extending in ZF2

I want to extend, for example, Zend\View\Helper\HeadMeta with my own class and I create a factory for it and call it by
public function getViewHelperConfig()
{
return array(
'factories' => array(
'MyHeadMeta' => __NAMESPACE__ . '\View\Helper\Service\MyHeadMetaService',
),
);
}
from Module.php, but I have
$this->view
is null in MyHeadMeta class if I call it by
$this->MyHeadMeta()->setCharset('utf-8');
in my view file.
How do I instantiate my view helper properly?
UPDATE
My class looks something like this:
MyHeadMeta.php
use Zend\View\Helper\HeadMeta;
class MyHeadMeta extends HeadMeta
{
//
}
UPDATE 2
MyHeadMetaService.php
class MyHeadMetaService implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$viewHelper = new MyHeadMeta();
// some settings to set...
return $viewHelper;
}
}
If you only extend the existing HeadMeta class then you should register it as an invokable as is done with the original HeadMeta view helper in the HelperPluginManager.
So change your config like this:
return array(
'invokables' => array(
'MyHeadMeta' => 'View\Helper\Service\MyHeadMetaService'
)
);
By the way I don't think it is necessary to use the full path with __NAMESPACE__. Just make sure the name points to the correct file and folder path of your class in the current module and declare the namespace constant in the class.

Zend Framework 2: Database connection in view helper

I found a few other posts relevant to this issue, however i wasn't able to achieve what i wanted so i decided to delete everything and start over with some help...
This is my work so far, which does the job but the data are provided hard coded in an array and i need to create a database connection to fetch those data.
In my module class i have:
public function getViewHelperConfig()
{
return array(
'factories' => array(
'liveStreaming' => function() {
return new LiveStreaming();
},
),
);
}
This is the code i have in my view helper:
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class LiveStreaming extends AbstractHelper
{
protected $liveStreamingTable;
public function __invoke()
{
$events = array(
'1' => array('name' => 'Event name',
'sport' => 'Soccer',
'time' => '11:30'),
'2' => array('name' => 'Event name',
'sport' => 'Soccer',
'time' => '17:00'),
);
return $events;
//this is what should be used (or something like that) to get the data from the db...
//return array('events' => $this->getLiveStreamingTable()->fetchAll() );
}
public function getLiveStreamingTable()
{
if (!$this->liveStreamingTable) {
$sm = $this->getServiceLocator();
$this->liveStreamingTable = $sm->get('LiveStreaming\Model\LiveStreamingTable');
}
return $this->liveStreamingTable;
}
}
So, i want to get the $events array from the database. I've created Application\Model\LiveStreaming and Application\Model\LiveStreamingTable (following the instructions of the ZF2 official tutorial) and i need some help proceeding to the next step, which should probably have to do with the service locator.
You seem to be almost there. The only thing missing is the ability to call $this->getServiceLocator(); from within the view helper (as the AbstractHelper doesn't provide this method).
There are two options
Inject the LiveStreamingTable into the view helper directly
inject the ServiceManager itself and create the LiveStreamingTable within the helper
Option 1 Make LiveStreamingTable a dependency of the view helper (type hint in constructor)
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
use LiveStreaming\Model\LiveStreamingTable;
class LiveStreaming extends AbstractHelper
{
protected $liveStreamingTable;
public function __construct(LiveStreamingTable $liveStreamingTable)
{
$this->liveStreamingTable = $liveStreamingTable;
}
public function getLiveStreamingTable()
{
return $this->liveStreamingTable;
}
}
And the factory becomes:
public function getViewHelperConfig()
{
return array(
'factories' => array(
'liveStreaming' => function($sl) {
// Get the shared service manager instance
$sm = $sl->getServiceLocator();
$liveStreamingTable = $sm->get('LiveStreaming\Model\LiveStreamingTable');
// Now inject it into the view helper constructor
return new LiveStreaming($liveStreamingTable);
},
),
);
}
Option 2 - Implement the ServiceLocatorAwareInterface (making it again a dependency of the view helper)
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class LiveStreaming extends AbstractHelper implements ServiceLocatorAwareInterface
{
protected $serviceLocator;
protected $liveStreamingTable;
public function __construct(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function setServiceLocator(ServiceLocatorInterface $serviceLocator);
public function getServiceLocator();
public function getLiveStreamingTable()
{
if (null == $this->liveStreamingTable) {
$this->liveStreamingTable = $this->getServiceLocator()->get('LiveStreaming\Model\LiveStreamingTable');
}
return $this->liveStreamingTable;
}
}
Your factory will then look like:
public function getViewHelperConfig()
{
return array(
'factories' => array(
'liveStreaming' => function($sl) {
// Get the shared service manager instance
$sm = $sl->getServiceLocator();
// Now inject it into the view helper constructor
return new LiveStreaming($sm);
},
),
);
}
Personally, I feel that Option 1 makes more sense from a Dependency Injection (DI) point of view - It's clear that the LiveStreamingTable is what is needed to create the view helper.
Edit
Make sure you have the LiveStreaming\Model\LiveStreamingTable service also registered with the service manager (as we request it in the above code when we did $sm->get('LiveStreaming\Model\LiveStreamingTable');)
// Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'LiveStreaming\Model\LiveStreamingTable' => function($sm) {
// If you have any dependencies for the this instance
// Such as the database adapter etc either create them here
// or request it from the service manager
// for example:
$foo = $sm->get('Some/Other/Registered/Service');
$bar = new /Directly/Created/Instance/Bar();
return new \LiveStreaming\Model\LiveStreamingTable($foo, $bar);
},
),
);
}

Getting module's name from model's name

I need to know a module name for a particular model, if I know only model's name.
For example, I have:
model Branch, stored in protected/modules/office/models/branch.php and
model BranchType stored in protected/modules/config/models/branchtype.php.
I want to know the module name of branch.php from the class of branchtype.php.
How to do this?
Unfortunately Yii does not provide any native method to determine the module name that model belongs to. You have to write your own algorithm to do this task.
I can suppose you two possible methods:
Store configuration for module's models in the module class.
Provide the name of your model using path aliases
First method:
MyModule.php:
class MyModule extends CWebModule
{
public $branchType = 'someType';
}
Branch.php
class Branch extends CActiveRecord
{
public function init() // Or somewhere else
{
$this->type = Yii::app()->getModule('my')->branchType;
}
}
In configuration:
'modules' =>
'my' => array(
'branchType' => 'otherType',
)
Second method:
In configuration:
'components' => array(
'modelConfigurator' => array(
'models' => array(
'my.models.Branch' => array(
'type' => 'someBranch'
),
),
),
)
You should write component ModelConfigurator that will store this configuration or maybe parse it in some way. Then you can do something like this:
BaseModel.php:
class BaseModel extends CActiveRecord
{
public $modelAlias;
public function init()
{
Yii::app()->modelConfigurator->configure($this, $this->modelAlias);
}
}
Branch.php:
class Branch extends BaseModel
{
public $modelAlias = 'my.models.Branch';
// Other code
}
Try this:
Yii::app()->controller->module->id.
Or inside a controller:
$this->module->id
in Yii2 try this:
echo Yii::$app->controller->module->id;
for more information see Get the current controller name, action, module

Categories