Yii Query Builder: Parametr binding using where() method - yii2

I have this code in my controller:
class ArchController extends Controller
{
public function actionIndex(string $date, array $rubric_id )
{
$articles = Article::find()->where('published < :date', [':date' => $date])
->andWhere(['in', 'rubric', $rubric_id])
->andWhere('ISNULL(arch)')->all();
...
It seems to me it is not safe because $rubric_id is user input. How can I make parametr binding, something like this:
':rubric_id' => $rubric_id

Yii uses parameter binding internally, so it is safe to use ->andWhere(['in', 'rubric', $rubric_id]). You can review implementation of InConditionBuilder to make sure of that.

Related

Query builder don't accept onlyTrashed()

I'm a beginner and cant find a solution to my problem. I trying to get "onlyTrashed" from my DB but Laravel 8 don't accept my query commands :( I tried many scenarios but unsuccessful.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\Category;
class CategoryController extends Controller{
public function AllCat(){
$categories = $trashCat = DB::table('categories')
->join('users','categories.user_id','users.id')
->select('categories.*','users.name')
->latest()
->paginate(5);
//$categories = Category::latest()->paginate(5);
// $trashCat = Category::onlyTrashed()->latest()->paginate(3);
return view('admin.category.index', compact('trashCat','categories'));
public function SoftDelete($id){
$delete = Category::find($id);`enter code here`
return Redirect()->back()->wiht('success',' Category Delete Successfuly');
Route::get('/softdelete/category/{id}', [CategoryController::class,'SoftDelete']);
Please make sure that your model imports and uses SoftDeletes trait to implement soft delete in your model and make sure that your table has deleted_at field, your model may look like below codes.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Category extends Model
{
use SoftDeletes;
And in your SoftDelete function within the controller, I think you miss delete() function, your function should look like:
public function SoftDelete($id) {
$delete = Category::find($id)->delete();
return redirect()->back()->with('success',' Category Delete Successfully');
}
Once you implement SoftDeletes trait into your model, delete() function should mark deleted by filling the deleted_at with timestamp or DateTime automatically. Once you implement the above codes, onlyTrashed() should work.
$categories = Category::latest()->paginate(5);
$trashCat = Category::onlyTrashed()->latest()->paginate(3);

cakephp 3 get property changes entity for dependent model(table)

I want to get the result set with extra field through afterFind. In cakePHP no afterFind function. So used protected function _getAttrName() {
return $this->_properties['name'];
}
inside the Entity class. But i did not get the output with 'attr_name' property. with find()
$this->loadModel('Products');
$this->loadModel('Attributes');
// Get the attributes to use as facets
$attributes = $this->Products->Attributes->find(['all',
'order' => 'Attributes.id',
])
->contain(['AttributeTypes'])
->where([
'Attributes.filterable' => true,
//'Attribute.required' => true,
])
->hydrate(false)
->toArray();
Can i get the solution?
You need to declare in your entity class what are the virtual properties you want to expose when converting to array or to json. This is the relevant section of the docs:
http://book.cakephp.org/3.0/en/orm/entities.html#exposing-virtual-properties
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Product extends Entity
{
protected $_virtual = ['attr_name'];
protected function _getAttrName() {
return $this->_properties['name'];
}
...
}

How can i use a component inside a Cell?

I'm looking for a way to use component inside a cell, is there any way ?
I tried :
$this->loadComponent('SessionsActivity');
My Cell :
namespace App\View\Cell;
use Cake\Core\Configure;
use Cake\View\Cell;
class UserCell extends Cell
My query :
$user = $this->Users
->find()
->where([
'Users.id' => $this->request->id
])
->contain([
'Towns' => function ($q) {
return $q->find('short');
},
'Countries' => function ($q) {
return $q->find('short');
}
])
->map(function ($user) {
$user->online = $this->SessionsActivity->getOnlineStatus($user);
return $user;
})
->first();
Using the same example at the CakePHP cells documentation, suppose you want to show the inbox for the connected user. You'd want to access the Auth component to take the connected user id.
AFAIK, Cells act like view-controller, a view part display.ctp file, and a controller part where you access the model to generate data for the view.
I'm using CakePHP 3.0 and $this->_registry doesn't work.
You could try:
$this->SessionsActivity = $this->_registry->load('SessionsActivity');
it is another question if you should use a component here

Generate link in cakephp using Html helper

I am trying to simply create a link in my controller using the Html helper and I get the below error although I have added the necessary helper:
Call to a member function link() on a non-object
public $helpers = array('Html', 'Form');
$url = $this->Html->link(
'',
'http://www.example.com/',
['class' => 'button', 'target' => '_blank']
);
You can use Helpers inside your view files but not inside your controller
http://book.cakephp.org/2.0/en/views/helpers.html#using-helpers.
For example in your index.ctp
echo $this->Html->link(
__('My link'),
'http://www.example.com/',
array('class' => 'button', 'target' => '_blank')
);
Enabling Html Helper in your Controller is same as in your code.
class ExamplesController extends AppController {
$helpers = array('Html', 'Form');
public function index() {
//
}
}
This is a good question. I think your a little confused with MVC and the separation of concerns the design pattern provides. Take a look (again) at how CakePHP implements MVC: http://book.cakephp.org/2.0/en/cakephp-overview/understanding-model-view-controller.html.
The important thing to remember is that your controllers should never be concerned with creating anchor tags. That's the job of your views. Since helpers are a way to keep your views DRY (Don't Repeat Yourself) having one thats sole responsibility is to create HTML elements is really handy. Views are dependent on controllers to determine what variables are set, what their value is, as well as what helpers are loaded. For more information on Helpers as well as components for controllers and behaviors for models check out http://book.cakephp.org/2.0/en/getting-started/cakephp-structure.html as well as each of their individual documentation pages:
Helpers - http://book.cakephp.org/2.0/en/views/helpers.html
Components - http://book.cakephp.org/2.0/en/controllers/components.html,
Behaviors - http://book.cakephp.org/2.0/en/models/behaviors.html.
Now that you have a better understanding of MVC, let's take a look at your specific issue. Your wanting to create a link in your controller. I assume it might be dynamic depending on some other variables so I'm going to roll with that.
A common problem that you can solve you want to show a login/logout link depending on if the user is already logged in.
In app/Controller/ExampleController.php
class ExampleController extends AppController {
public $components = array('Auth');
public $helpers = array('Html', 'Form');
public function beforeRender() {
parent::beforeRender();
//if Auth::user() returns `null` the user is not logged in.
if ($this->Auth->user() != null) {
$logInOutText = 'Log out';
$logInOutUrl = array('controller' => 'users', 'action' => 'login');
} else {
$logInOutText = 'Log in';
$logInOutUrl = array('controller' => 'users', 'action' => 'logout');
}
$this->set(compact('logInOutText', 'logInOutUrl'));
}
}
You can then so something simple in your view. In this case I'm choosing the default layout because I want the links in every rendered page. app/View/Layouts/default.ctp
<!-- More HTML above -->
<?php
// "Html" in `$this->Html` refers to our HtmlHelper. Note that in a view file
// like a `.ctp`, `$this` referes to the View object, while above in the
// controller `$this` refers to the Controller object. In the case
// `$this->Html`, "Html" would refer to a component. The same goes for Models
// and behaviors.
echo $this->Html->link($logInOutText, $logInOutUrl); // Easy!
?>
<!-- More HTML below -->
I hope this helps. I know it's a lot to put together at one time.
Though it is not good practice. However still if you need this you can use following code in your controller
App::uses('HtmlHelper', 'View/Helper');
$yourTmpHtmlHelper = new HtmlHelper(new View());
$url=$yourTmpHtmlHelper->link(
'',
'http://www.example.com/',
['class' => 'button', 'target' => '_blank']
);
This should work for cakephp 2.*
Thanks

zend framework 2, return the rendered contents of a view inside a JSON Model

I am trying to create a JsonModel with an item in the variables 'html' containing the current rendered view. I would like to add this code to an event:
rather than this method: How to render ZF2 view within JSON response? which is in the controller, I would like to automate the process by moving it to an Event
I have the strategy in my module.config.php:
'strategies' => array(
'ViewJsonStrategy',
)
I have set up a setEventManager in the controller:
$events->attach(MvcEvent::EVENT_RENDER, function ($e) use ($controller) {
$controller->setRenderFormat($e);
}, -20);
Is this the best event to attach it to? would the RENDER_EVENT be better?
Now I would like to change the render of the page based on !$this->getRequest()->isXmlHttpRequest(), (commented out for debug)
public function setRenderFormat($e)
{
//if(!$this->getRequest()->isXmlHttpRequest())
//{
$controller = $e->getTarget();
$controllerClass = get_class($controller);
//Get routing info
$controllerArr = explode('\\', $controllerClass);
$currentRoute = array(
'module' => strtolower($controllerArr[0]),
'controller' => strtolower(str_replace("Controller", "", $controllerArr[2])),
'action' => strtolower($controller->getEvent()->getRouteMatch()->getParam('action'))
);
$view_template = implode('/',$currentRoute);
$viewmodel = new \Zend\View\Model\ViewModel();
$viewmodel->setTemplate($view_template);
$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($viewmodel, $viewmodel);
$jsonModel = new JsonModel();
$jsonModel->setVariables(array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1,2,3,4,5,6)
));
return $jsonModel;
//}
}
Strangely, (or not) this code works and produces the $jsonModel, however is doesn't overwite the normal HTML view with the json, but the same code (without the event) in a controller method, overwrites perfectly.
p.s Is there a better method to do the whole concept?
p.p.s how can I obtain the current View Template from within the controller, without resorting to 8 lines of code?
Thanks in advance!
Aborgrove
you are returning the view model from an event I thinks this doesn't have any effect in current viewmanager view model, fetch the current viewmodel from viewmanager and call setTerminal(true). or replace the created jsonmodel using the viewmanager