I'm trying to use Session component in custom component (CakePHP 2.3) but when I call Session component functions I get: Fatal error: Call to a member function read() on a non-object in ...\app\Controller\Component\CartComponent.php on line 7
My CartComponent looks like that:
<?php
App::uses('Component', 'Controller');
class CartComponent extends Component {
public $components = array('Session');
function hasItems() {
$cart = $this->Session->read('Cart');
return $cart != null && count($cart) > 0;
}
}
?>
And I use it in controller:
<?php
class OrdersController extends AppController {
public $name = 'Orders';
public $components = array('Cart', 'Email');
function beforeFilter() {
parent::beforeFilter();
if ($this->Cart->hasItems()) {
$this->Auth->allow('add_item', 'remove_item', 'cart');
} else {
$this->Auth->allow('add_item', 'remove_item', 'cart', 'make');
}
}
}
?>
For using session inside the custom component I tried with
public $components = array('Session');
and then called it by using
$this->Session->read('Cart');
but I cant able to use it and I start to use
CakeSession::read('Cart')
Now it works Hope it will used for you note I used in cake php version > 2
If you want to use Session in your Component Use-
$test = CakeSession::read('user');
print_r($test);
You should use as bellow
class YourComponent extends Component {
public function initialize(Controller $controller){
$this->controller = $controller;
if (!isset($this->controller->presetVars)) {
$this->controller->presetVars = true;
}
$model = $this->controller->modelClass;
if (!empty($settings['model'])) {
$model = $settings['model'];
}
if ($this->controller->presetVars === true) {
// auto-set the presetVars based on search definitions in model
$this->controller->presetVars = array();
$filterArgs = array();
if (!empty($this->controller->$model->filterArgs)) {
$filterArgs = $this->controller->$model->filterArgs;
}
foreach ($filterArgs as $key => $arg) {
if ($args = $this->_parseFromModel($arg, $key)) {
$this->controller->presetVars[] = $args;
}
}
}
foreach ($this->controller->presetVars as $key => $field) {
if ($field === true) {
if (isset($this->controller->$model->filterArgs[$key])) {
$field = $this->_parseFromModel($this->controller->$model->filterArgs[$key], $key);
} else {
$field = array('type' => 'value');
}
}
if (!isset($field['field'])) {
$field['field'] = $key;
}
$this->controller->presetVars[$key] = $field;
}
/* now you can use Component existing in your Component :) */
public function sayHello(){
$this->controller->Session->setFlash(__('Hello you'));
}
}
Related
I have an UserEventListener which implements EventListenerInterface.
In the event: afterLogin($event){} I would like to redirect the user if the profile is not complete, I can't figure out how to do redirect with the $event parameter
Edit:
here is the code of the UserEventListener:
<?php
namespace App\Event;
use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceInterface;
use Authentication\AuthenticationServiceProviderInterface;
use Authentication\Middleware\AuthenticationMiddleware;
use Psr\Http\Message\ServerRequestInterface;
use Cake\Event\EventListenerInterface;
use Cake\Datasource\FactoryLocator;
use Cake\Log\Log;
class UserEventListener implements EventListenerInterface
{
public function implementedEvents(): array
{
return [
'Users.Authentication.afterLogin' => 'afterLogin',
//'Users.Authentication.afterLogout' => 'afterLogout'
];
}
public function afterLogin($event)
{
$profilesTable = FactoryLocator::get('Table')->get('Profiles');
$profiles = $profilesTable->find()
->where(['user_id' => $event->getData('user')->id])
->order(['id' => 'DESC'])->toList();
if((count($profiles) == 1) && $profiles[0]->mobile == "" ){
//-- here I would like to redirect --------
//return $event->getSubject()->redirect(['Controller'=>'Profiles', 'action' => 'edit',$event->getData('user')->id]);
}
}
}
I want to display data on the controller
public function __construct() {
parent:: __construct();
if(!isset($_SESSION)){
session_start();
}
if (!$_SESSION['logged_in']) {
redirect('auth/login');
}
$managemenu = new Managemenu();
$get_data = $managemenu->index($_SESSION['admin_level'],$GLOBALS['PAGE_DISTRIK']);
if(empty($get_data['validPage'])){
redirect('auth/login');
}
$this->getdata = $get_data;
$this->load->model('Model_distrik');
}
public function index()
{
$data['page'] = 'v_distrik';
$data['title'] = 'List Distrik';
$data['menu'] = $this->getdata['menu'];
$data['distrik'] = $this->Model_distrik->getDataDistrik();
echo "<pre>";
print_r ($data['distrik']);
echo "</pre>";
die();
$this->load->view('main',$data);
}
I've tried a number of times but the results are like
this error message: undefined property: district :: $ model_district
class Model_distrik extends CI_Model {
public function getDataDistrik(){
$this->db->select('*');
$this->db->from('distrik');
$this->db->where("Deleted", 0);
$query = $this->db->get()->result_array();
return $query;
}
}
I have a site built with CakePHP, default it doesn't allow subdomain embed on iframe.
I configured Frame Option on nginx/conf.d and now my homepage can be embedded in an iframe of a subdomain.
However, another post cannot be embedded on a subdomain's iframe. (exp: http://example.net/postabc will not display). I tried to change options on Header security middleware(please read below).
Is there anywhere I need to change the configuration to so all my posts can be displayed?
<?php
namespace Cake\Http\Middleware;
use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class SecurityHeadersMiddleware
{
protected $headers = [];
public function noSniff()
{
$this->headers['x-content-type-options'] = 'nosniff';
return $this;
}
public function noOpen()
{
$this->headers['x-download-options'] = 'noopen';
return $this;
}
public function setReferrerPolicy($policy = 'same-origin')
{
$available = [
'no-referrer', 'no-referrer-when-downgrade', 'origin',
'origin-when-cross-origin',
'same-origin', 'strict-origin', 'strict-origin-when-cross-origin',
'unsafe-url'
];
$this->checkValues($policy, $available);
$this->headers['referrer-policy'] = $policy;
return $this;
}
public function setXFrameOptions($option = 'allow-from', $url = 'http://subdomain.example.net')
{
$this->checkValues($option, ['deny', 'sameorigin', 'allow-from']);
if ($option === 'allow-from') {
if (empty($url)) {
throw new InvalidArgumentException('The 2nd arg $url can not be empty when `allow-from` is used');
}
$option .= ' ' . $url;
}
$this->headers['x-frame-options'] = $option;
return $this;
}
public function setXssProtection($mode = 'block')
{
$mode = (string)$mode;
if ($mode === 'block') {
$mode = '1; mode=block';
}
$this->checkValues($mode, ['1', '0', '1; mode=block']);
$this->headers['x-xss-protection'] = $mode;
return $this;
}
public function setCrossDomainPolicy($policy = 'all')
{
$this->checkValues($policy, ['all', 'none', 'master-only', 'by-content-type', 'by-ftp-filename']);
$this->headers['x-permitted-cross-domain-policies'] = $policy;
return $this;
}
protected function checkValues($value, array $allowed)
{
if (!in_array($value, $allowed)) {
throw new InvalidArgumentException(sprintf(
'Invalid arg `%s`, use one of these: %s',
$value,
implode(', ', $allowed)
));
}
}
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next)
{
$response = $next($request, $response);
foreach ($this->headers as $header => $value) {
$response = $response->withHeader($header, $value);
}
return $response;
}
}
I really need to know this issue to finish my work.
Here I'll give a example envolving model and controller.
I want to pass $final_name from controller to beforeSave() of my model
public function admin_add() {
if($this->request->is('post')) {
if($this->data['Client']['file']['tmp_name'] != '') {
// Upload block
$tmp_file = $this->data['Client']['file']['tmp_name'];
$file = new File($tmp_file);
if($file->mime() == "image/jpeg" or "image/png") {
$ext = explode('.', $this->data['Client']['file']['name']);
$name = md5($this->data['Client']['file']['name']);
$file->copy(IMG_DIR . 'portfolio\\' . $name . '.' . end($ext));
$final_name = $name . "." . end($ext); // File name with extension
}
// If save
if($this->Client->save($this->request->data)) {
$this->Session->setFlash('Client cadastrado com sucesso!', 'admin_flash');
}
}
}
}
In my client model
public function beforeSave($options = array()) {
if($this->data['Client']['file']['name'] != null) {
$this->data['Client']['file'] = $final_name;
}
return parent::beforeSave($options);
}
In Controller
$this->request->data['Client']['final_name'] = $name . "." . end($ext);
In Model
public function beforeSave($options = array()) {
if($this->data['Client']['file']['name'] != null) {
$this->data['Client']['file'] = $this->data['Client']['final_name'];
}
return parent::beforeSave($options);
}
Update for CakePHP3
Pass variable from controller to table beforeSave, afterSave ?
// Examples
// In Controller
$this->Article->save($data, ['passVariable' => 'passedData']);
// in Table
public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options)
{
if (isset($options['passVariable'])) {
// implement your code
}
}
Read more: https://api.cakephp.org/3.8/class-Cake.ORM.Table.html#_save
But good place to modify data before save like asked in question are:
https://book.cakephp.org/3.0/en/orm/saving-data.html#before-marshal or
https://book.cakephp.org/3.0/en/orm/entities.html#accessors-mutators
I'm developing a REST api for a application, and everething went fine up until now...
I'm building a header with login data, GET and DELETE work fine but when I try to send a PUT or POST request I get 404...
When authorization is off (i.e., I do not check it in cake) everything works fine.
Here's the controller code:
class SitesController extends AppController {
var $uses = array("Site");
var $name = 'Sites';
var $scaffold;
var $components = array('RequestHandler','Security');
function beforeFilter() {
$this->Security->loginOptions = array(
'type'=>'basic'
);
$this->Security->loginUsers = array(
'lukasz'=>'blabla',
'test'=>'test'
);
$this->Security->requireLogin();
}
function index() {
$sites = $this->Site->find('all');
$this->set(compact('sites'));
}
function view($id) {
$site = $this->Site->findById($id);
$this->set(compact('site'));
}
function add() {
if($this->data != null) {
$this->Site->create();
if($this->Site->save($this->data)) {
$message = array('Deleted');
} else {
$message = $this->data;
}
$this->set(compact("message"));
}
}
function edit($id) {
$this->Site->id = $id;
if ($this->Site->save($this->data)) {
$message = array('Saved');
} else {
$message = array('Error');
}
$this->set(compact("message"));
}
function delete($id) {
if($this->Site->delete($id)) {
$message = array('Deleted');
} else {
$message = array('Error');
}
$this->set(compact("message"));
}
}
And here's how I send requests:
http://bin.cakephp.org/view/165115685
http://bin.cakephp.org/view/1477117088
I suspect you're running into the CSRF protection (form spoofing protection) the SecurityComponent applies to all POST and PUT requests. Try turning it off using the $validatePost option.