Fairly experienced programmer but new to CakePHP 2.1 and spending my day struggling to get a custom Helper to work in View by following the manual: http://book.cakephp.org/2.0/en/views/helpers.html
I've not been able to find an answer and would greatly appreciate any Cake expertise.
My helper file in app/Helper/EntriesHelper.php:
App::uses('AppHelper', 'View/Helper');
class EntriesHelper extends AppHelper {
public function __construct(View $view, $settings = array()) {
parent::__construct($view, $settings);
}
public function spanWrapper($content) {
if(substr($content,0,1) == "#") {
return "<span class='label label-warning'>$content</span>";
}
else if(substr($content,0,1) == "#") {
return "<span class='label label-default'>$content</span>";
}
else if (substr($content,0,4) == "http" || substr($content,0,3) == "www") {
return "<span class='label'>$content</span>";
}
return $content;
}
}
And my controller in app/Controller/EntriesController:
App::uses('AppController', 'Controller');
class EntriesController extends AppController {
public $helpers = array('Form', 'Html', 'Js', 'Time');
#public $components = array('RequestHandler');
#public $viewClass = 'Json';
public function index() {
$helpers[] = 'spanWrapper';
$this->Entry->recursive = 1;
$this->set('entries', $this->paginate());
#$this->set('_serialize', array('entries'));
}
}
But a call from my View fails:
$this->Entries->spanWrapper($entry['Entry']['title']);
With the error:
Notice (8): Undefined property: View::$Entries [CORE/Cake/View/View.php, line 806]
Fatal error: Call to a member function spanWrapper() on a non-object in <path removed>/app/View/Entries/index.ctp on line 35
So the notice of undefined property is presumably causing the fatal error ... but why so, if it's implemented per the cookbook?
Darren
The correct syntax is $this->helpers[] = 'spanWrapper'; when loading a helper within a method, or add it to your public $helpers array instead.
If you want to use your helper in the entire controller, you should add it to the $helpers array in your EntriesController:
class EntriesController extends AppController {
public $helpers = array('Form', 'Html', 'Js', 'Time', 'Entries');
/* ... */
}
If you need the helper in your entire application, you can add it to the AppController the same way.
If on the other side you only need it in one single view, you may choose to only load it there dynamically. In your view, call HelperCollection->view() just before you want to use the helper for the first time:
$this->Helpers->load('Entries');
All three methods are documented very well in the CakePHP book.
Related
I have a problem where the value for the cookie I set is not being kept if switching to a different section (controller) with CakePHP3.
I establish the original cookie in the AppController so it is sitewide:
<?php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
use Cake\Http\Cookie\Cookie;
use Cake\Http\Cookie\CookieCollection;
class AppController extends Controller
{
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Cookie');
//set up initial cart cookie
$this->response = $this->response->withCookie(
(new Cookie('cart'))
->withPath('/')
->withValue(json_encode([]))
->withExpiry(new \DateTime('+1 month'))
);
}
I then have it set up in the CartController to add selected items to the cart cookie:
<?php
// src/Controller/CartController.php
namespace App\Controller;
use Cake\I18n\Time;
use Cake\Http\Cookie\Cookie;
use Cake\Http\Cookie\CookieCollection;
class CartController extends AppController
{
public function index()
{
$cart = json_decode($this->request->getCookie('cart'));
$add_cart = ($this->request->getQuery('add') == null ? [] : $this->request->getQuery('add'));
if (count($add_cart) > 0) {
foreach($add_cart as $ac) {
if(!in_array($ac, $cart)) {
$cart[] = $ac;
}
}
}
//replace cookie
$this->response = $this->response->withCookie(
(new Cookie('cart'))
->withPath('/')
->withValue(json_encode($cart))
->withExpiry(new \DateTime('+1 month'))
);
$this->loadModel('Books');
$cart_items = [];
foreach($cart as $cartp) { //'contain' => ['BookTypes'],
$book = $this->Books->get($cartp, ['fields' => array('id','name','description')]);
$cart_items[] = $book;
}
$this->set(compact('cart_items'));
}
If I stay within "Cart", the cookie keeps the value. However, as soon as I move to any other page (home page or browsing books), the cookie value is reset to empty (an empty array).
What is causing this?
I found my problem.
Had to move the initial cookie from the initialize() to beforeFilter() in AppController.php and now it seems to be working.
I'm trying to force my app to check every time it loads a model or controller depending on which is my session value.
This is actually running, but just when I get throw this model.
class News_model extends CI_Model {
public function __construct()
{
parent::__construct();
if($this->session->dbname=='db1'){
$this->db=$this->load->database('db1', TRUE);
}
else{
$this->db=$this->load->database('db2', TRUE);
}
}
public function get_news($slug = FALSE)
{
if ($slug === FALSE)
{
$query = $this->db->get('news');
return $query->result_array();
}
$query = $this->db->get_where('news', array('slug' => $slug));
return $query->row_array();
}
}
But I do not war to include that __construct code to all my models or controllers.
I've tried to add on my autoload.php
$autoload['model'] = array('General');
Where my General code is something like this.
class General extends CI_Model {
function __construct()
{
parent::__construct();
if($this->session->dbname=='db1'){
$this->db=$this->load->database('db1', TRUE);
}
else{
$this->db=$this->load->database('db2', TRUE);
}
}
}
How can I do it?
You can do it by creating a base model which will be extended by your models that require the database check.
I have simplified the checking and loading code. A simple ternary determines the string to use and stores it in the variable $dbname. That variable is used to load the database, i.e. $this->load->database($dbname);.
I don't believe you need the second argument to load::database() which means you don't need to set $this->db explicitly. If I'm wrong, use
$this->db = $this->load->database($dbname, TRUE);
Below is the "base" model. The prefix of the file name is determined in config.php with the setting $config['subclass_prefix'] = 'MY_'; Adjust your base model's file and class name to match the 'subclass_prefix' you use.
/application/core/MY_Model.php
<?php
class MY_Model extends CI_Model
{
public function __construct()
{
parent::__construct();
$dbname = $this->session->dbname == 'db1' ? 'db1' : 'db2';
$this->load->database($dbname);
}
}
Use the above to create other models like so...
class News_model extends MY_Model
{
public function get_news($slug = FALSE)
{
if ($slug === FALSE)
{
$query = $this->db->get('news');
return $query->result_array();
}
$query = $this->db->get_where('news', array('slug' => $slug));
return $query->row_array();
}
}
In my RedpCategory table I use cat_id as primaryKey, something like in my model below
in RedpCategory model:
<?php
App::uses('AppModel', 'Model');
class RedpCategory extends AppModel {
public $useTable = 'redp_category';
public $name = 'RedpCategory';
public $primaryKey = 'cat_id';
//
//
}
in my view:
public function view($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid redeem category'));
}
$redp_categories = $this->RedpCategory->findById($id);
if (!$redp_categories) {
throw new NotFoundException(__('Invalid redeem category'));
}
$this->set('redp_categories', $redp_categories);
}
I got an error when I click on a category name link: "Undefined column: 7 ERROR: column
RedpCategory.id does not exist"
How can I solve with this problem?
Any answer will be appreciated.Thank you in advanced.
findById() will search for the literal 'id' field.
Try switching your find statement to:
$this->RedpCategory->findByCatId($id);
Edit: redacted incorrect information
MY first time creating a custom helper. I'm getting an error in my Controller Code that I"m calling a a method on a non existed object (helper). Yet i believe my helper "BM" is being loaded successfully because i'm not getting any errors on loading helpers.
Error: Call to a member function mcpGetActiveMerchantID() on a non-object
File: C:\wamp\www\bm\app\Controller\MCPController.php
Line: 412
I have placed BMHelper.php into my View\Helper\ directory.
<?php
class BMHelper extends AppHelper{
public function mcpGetActiveMerchant(){
return $this->Session->read('Auth.ActiveMerchant');
}
public function mcpGetActiveMerchantID() {
$activemerchant = $this->Session->read('Auth.ActiveMerchant');
foreach($activemerchant as $key => $value) {
$merchant_id = $key;
}
return $merchant_id;
}
}
?>
Then in my Controller I have this:
<?php
class MCPController extends AppController {
public $helpers = array('Html', 'Form', 'Session','BM','Js' => array('Jquery'));
public function walkinadd() {
$test = $this->BM->mcpGetActiveMerchantID(); //Line 412
}
}
?>
HEre is the error again (same as the error I pasted at the top)
Error: Call to a member function mcpGetActiveMerchantID() on a non-object
File: C:\wamp\www\bm\app\Controller\MCPController.php
Line: 412
Anyone know what is wrong?
Helpers are to be used in Views not Controllers, though you could do:
public function walkinadd() {
$view = new View($this);
$bm = $view->loadHelper('BM');
$test = $bm->mcpGetActiveMerchantID();
}
TagController
public function view($id = null) {
if ($this->request->data != null) {
$this->Common->replyarticleAdd($this);
}
}
CommonComponent
/*
App::uses('Link', 'Model');
App::uses('User', 'Model');
App::uses('AppController', 'Controller');*/
I think , I should write it and it loads model but not effect.
ClassRegistry::init('Article');
App::uses('Article', 'Model');
ClassRegistry::init('Article');
App::uses('Article', 'Model');
class CommonComponent extends Component {
var $uses = array('Article');
public function replyarticleAdd($that = null) { // $this error can not re-assign.
debug($that->request->params['pass'][0]);
if ($that->request->params['pass'][0] != null) {
$this->Article->create(); // that is no effect
Error Call to a member function create() on a non-object
File: G:\pleiades\xampp\htdocs\cakephp\app\Controller\Component\CommonComponent.php
Line: 13 = $this->Article->create();
In controller create is ok but in component it cant. How can I do this?
In the component, try to work with the models this way:
App::uses('Article', 'Model');
$Article = new Article();
$Article->create();
Components do not have the $uses property, like controllers.
You can also use:
$Article = ClassRegistry::init('Article');
$Article->create();