Laravel 5 Constant define - php

I tried all the options. Still, it is showing "Constant expression contains invalid operations". I am using Laravel 5.5, Please Help. I need to define table name in constant and use it in Model.
I wrote in Model:
protected $table = Config::get('constants.dbTable.EMAILTEMPLATE');
And In constant.php inside Config:
return [ 'langs' =>
[
'es' => 'www.domain.es',
'en' => 'www.domain.us' // etc
],
'siteTitle' => 'HD Site',
'pagination' => 5,
'tagLine' => 'Do the best',
'dbTable'=>[
'EMAILTEMPLATE' => 'stmd_emailTemplate'
]
];
I want to use emailTemplate table.

Based on the code you have posted in the comment, you are trying to assign a value into a property in your model but you are assigning it too early (assumed from the keyword protected.) You can't do this:
class SomeModel extends Model
{
protected $someProperty = config('some.value'); // Too early!
}
because you are trying to initialize a property that requires a run-time interpretation.
There's a workaround; use your constructor.
class SomeModel extends Model
{
protected $someProperty; // Define only...
public function __construct() {
parent::__construct(); // Don't forget this, you'll never know what's being done in the constructor of the parent class you extended
$this->someProperty = config('some.value');
}
}

Related

Cake PHP 2 save data via model in Event Listener

I've got an event listener in my project's Lib/Event directory and a model called QueueManagerJob.
My application dispatches an event at some point and I'd like to save an entry into my database through my model. When my event is dispatched, it runs a store method in the listener and it's here where I'm referencing my model and am trying to save it.
I've pulled the model in via the $uses array but I'm getting the following error:
Call to a member function set() on null
<?php
App::uses('CakeEventListener', 'Event', 'CakeLog');
class DispatchJobListener implements CakeEventListener {
public $uses = array('QueueManagerJob');
public function implementedEvents() {
return array(
'QueueManagerModule.QueueManagerJob.dispatchJob' => 'store'
);
}
/**
* Store the data
*/
public function store($event) {
$event->stopPropagation();
$job = [
'queue' => 'default',
'payload' => json_encode([]),
'attempts' => 0,
'reserved_at' => null,
'available_at' => date('Y-m-d H:i:s'),
'created_at' => date('Y-m-d H:i:s')
];
$this->QueueManagerJob->set($job);
// invalid
if (!$this->QueueManagerJob->validates()) {
// $this->QueueManagerJob->validationErrors;
// ...
}
// save the job
$this->QueueManagerJob->save($job);
}
}
Your class only implements an interface, there is no further logic that would make use of the $uses property.
The $uses property is only recognized out of the box by controllers, if you need to load models in other places, then you have to use ClassRegistry::init(), like:
App::uses('ClassRegistry', 'Utility');
// ...
$QueueManagerJob = ClassRegistry::init('QueueManagerJob');
Also note that App::uses() only accepts two arguments, the class name and the package name, the third argument in your example won't do anything!

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.

Is is a good practice to call a method inside another method? - PHP

I would like to know if it's recommended to do this:
class User {
public function __construct() {
parent::__construct();
}
public function exists($token) {
//return true if token exists otherwise return false
}
public function createSession($token) {
if($this->exists($token))
//create session
else
//redirect
}
}
I think it could be not recommended in case of a change in the exists method of the class but I think that'll not happen, What do you recommend me to do?
There's nothing wrong with calling methods from other methods. In many designs, it's critical that you do this. This allows you to create subclasses that redefine the method, and the new definition will be called.
So if you do:
class SpecialUser extends User {
public function exists($token) {
// determine token existence in some other way
}
}
You can then do:
$s = new SpecialUser;
$s->createSession($someToken);
and it will make use of the special way that SpecialUser checks tokens.
I do that all the time, when i notice my method is too long i segregate it and create another private method or protected method. Another reason is so it could be reuse for another method.
Here's an example:
class Download extends PHPExcel{
public function excel2007()
{
$excelFormat = $this->excelFormat();
}
public function excel2003()
{
$excelFormat = $this->excelFormat();
}
private function excelFormat()
{
return [
'font_bold' => [
'font' => array(
'bold' => true
)
],
'font_size' => [
'font' => array(
'size' => 10
)
],
'align_center' => [
'alignment' => array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER)
]
];
}
}

Getting the controller action before behaviour code runs in Yii2

I'm trying to execute some code inside a Yii2 controller as I need some code from the model to be accessible within the behaviors section so I can pass the model as a parameter and avoid running duplicate queries; however I also need to be able to find out what action is being called, but I am not having much luck.
I have tried using beforeAction but it seems this gets run AFTER the behaviours code runs, so that doesn't help me.
I then tried using init, but it seems the action isn't available via $this->action->id at that point.
Some example code:
class MyController extends Controller {
public $defaultAction = 'view';
public function init() {
// $this->action not available in here
}
public function beforeAction() {
// This is of no use as this runs *after* the 'behaviors' method
}
public function behaviors() {
return [
'access' => [
'class' => NewAccessControl::className(),
'only' => ['view','example1','example2'],
'rules' => [
[
'allow' => false,
'authManager' => [
'model' => $this->model,
'other_param' => $foo,
'other_param' => $bar,
],
'actions' => ['view'],
],
// everything else is denied
],
],
];
}
public function viewAction() {
// This is how it is currently instantiated, but we want to instantiate *before* the behavior code is run so we don't need to instantiate it twice
// but to be able to do that we need to know the action so we can pass in the correct scenario
$model = new exampleModel(['scenario' => 'view']);
}
}
authManager is simply a reference to a member variable inside an extension of the AccessRule class.
Is there anyway I can do this?
Well, if I get you right, you are looking for something like this:
public function behaviors()
{
$model = MyModel::find()->someQuery();
$action = Yii::$app->controller->action->id;
return [
'someBehavior' => [
'class' => 'behavior/namespace/class',
'callback' => function() use ($model, $action) {
//some logic here
}
]
];
}
Because behaviors() is just a method, you can declare any variables and add any logic that you want in it, the only one convention that you must follow - is that return type must be an array.
If you use your custom behavior, you are able to use events() method where you can bind your behavior's methods to certain events. E.g.
class MyBehavior extends Behavior
{
public function events()
{
return [
\yii\web\User::EVENT_AFTER_LOGIN => 'myAfterLoginEvent',
];
}
public function myAfterLoginEvent($event)
{
//dealing with event
}
}
In this example myAfterLoginEvent will be executed after user successfully login into application. $event variable will be passed by framework and depending of event type it will contain different data. Read about event object
UPDATE:
As I can see now my answer was more generic about events and behaviors. And now when you added code, I can suggest to you to override behavior's beforeAction($action) method with the following code:
public function beforeAction($action)
{
$actionID = $action->id;
/* #var $rule AccessRule */
foreach ($this->rules as &$rule) {
$model = &$rule->authManager['model'];
//now set model scenario maybe like this
$model->scenario = $actionID;
}
//now call parent implementation
parent::beforeAction($action);
}
Also take a look at AccessControl implementation of beforeAction method, it invokes for each rule allows method with passing current action to it as a parameter. So if you have class that extends AccessRule, you can either override allows($action, $user, $request) method or matchCustom($action) method to set appropriate model scenario. Hope this will help.
One more alternative:
override controller's runAction($id, $params = []) method. Here $id is actionID - exactly what you need. Check id, set appropriate model scenario and call parent::runAction($id, $params);

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