cake php link to the current page with different prefix - cakephp

In my default layout I would like to show link which points to the current page but with different prefix. I am using prefix 'language' to use address like www.site.com/eng/controller/action/param.
I tried $this->Html->link('eng', array('language' => 'eng') );
But this creates link with url eng/controller/action without passed arguments, without named arguments and without url params.
How I can do this? I would prefer elegant solution like 1 line of code - I know it can be done but can't find it :(.

Try this:
// helper method, possibly AppHelper, or in AppController and set a view var
function getCurrentParams() {
$route = Router::currentRoute();
$params = $this->request->params;
$pass = $params['pass'];
$named = $params['named'];
unset($params['pass'], $params['named']);
if (!empty($route->options['pass'])) {
$pass = array();
}
return array_merge($params, $named, $pass);
}
$params = $this->SomeHelper->getCurrentParams();
$params['language'] = 'eng';
// use $params for your link now

in my case this easy solution worked too!
<?php
App::uses('HtmlHelper', 'View/Helper');
class MyHtmlHelper extends HtmlHelper {
public function url($url = null, $full = false) {
if(!isset($url['language']) && isset($this->params['language']) && is_array($url)) {
$url['language']= $this->params['language'];
}
if(count($url) == 1 && isset($url['language'])){
$params = $this->params;
$url = array_merge($params['pass'],$url);
}
return parent::url($url, $full);
}
}
and in AppController
public $helpers = array(
...
'Html' => array('className' => 'MyHtml')
...
);

$this->Html->link('eng', array('language' => 'eng', 'pass') );

Something like this should work:
$url = Router::parse($this->here);
$url['language'='end';
$this->Html->link('eng', $url);
It's not one line, but you could compress it into one line but it would be pretty unreadable.
You could wrap it in a helper / function which would be a one line call though ;-)

Related

CakePHP: finding data after save

I'm working on an edit method. After saving data, an email is sent out with the changes made during the edit. Everything works except for one infuriating but crucial bug. Here it is distilled down very simply:
$data = $this->SupportTicket->readForView($st_id);
$this->SupportTicket->id = $st_id;
if ($this->SupportTicket->save($this->request->data)) {
//call custom model method to pull view data
$data = $this->SupportTicket->readForView($st_id);
//do something with this data
}
The issue is that $data comes out with the pre-save data. So what I then try to do with the new data doesn't work.
I can't just use $this->request->data because it doesn't have the full data that I want in it.
The save does however work. If I refresh the view method for the same record, it shows as updated. So it's saving, but when I do the find after saving it is giving me old data.
Any ideas?
Update: it doesn't happen with findById($st_id) so it must be something to do with my custom method. Code:
public function readForView($id)
{
$data = $this->find('first', array(
'conditions' => array(
'SupportTicket.id' => $id
),
'contain' => array(
'User',
'Owner'
)
));
if (empty($data)) {
throw new notFoundException('Ticket not found');
}
$data['SupportTicket']['type_long'] = $this->getLongType($data['SupportTicket']['type']);
$data['SupportTicket']['status_long'] = $this->getLongStatus($data['SupportTicket']['status']);
$data['SupportTicket']['name'] = 'Support Ticket #' . $data['SupportTicket']['id'] . ' - ' . $data['SupportTicket']['title'];
return $data;
}
Copying the code from this method into the Controller gives the same result.
I've found this helpful: https://edivad.wordpress.com/2008/04/15/cakephp-disable-model-queries-caching/
By model:
class Project extends AppModel {
var $cacheQueries = false;
...
By function:
function someFunction {
$this->Model->cacheQueries = false;
...
try using last Insert ID
$id=$this->getLastInsertID();
public function readForView($id)

Avoid creating a view for each AJAX function at CakePHP

I am trying to avoid creating a view for each AJAX function I am using at my controller. (as i don't manipulate the resulting data in any way and in most cases is just a boolean value)
I am using RequestHandler component at my controller:
var $components = array('RequestHandler');
And I added this in routes.php
Router::parseExtensions('json');
I am trying to make this function to work, but I am getting a null value:
public function test(){
$this->layout = 'ajax';
$result = '1';
$this->set('_serialize', $result);
}
To access to the json version of the function i use this URL finishing in .json to avoid loading any view:
http://localhost/cakephp/demoController/test.json
I have been following the steps from CakePHP documentation:
http://book.cakephp.org/2.0/en/views/json-and-xml-views.html#json-and-xml-views
What am I doing wrong? Why don't I get the expecting result and instead I get a null?
Also, if I try to to serialize some array, like this one:
$result = array('demo' => '1');
$this->set('_serialize', $result);
I'm getting this notice:
Notice (8): Undefined index: 1 [CORE\Cake\View\JsonView.php, line 89]Code Context $data = array();
foreach ($serialize as $key) {
$data[$key] = $this->viewVars[$key];$view = null
$layout = null
$serialize = array(
'demo' => '1'
)
$data = array()
$key = '1'JsonView::render() - CORE\Cake\View\JsonView.php, line 89
Controller::render() - CORE\Cake\Controller\Controller.php, line 957
Dispatcher::_invoke() - CORE\Cake\Routing\Dispatcher.php, line 193
Dispatcher::dispatch() - CORE\Cake\Routing\Dispatcher.php, line 161
require - APP\webroot\index.php, line 92
[main] - ROOT\index.php, line 42{"1":null}
As far as I understand the documentation you have to specify a view variable and then refer to this variable when you use the _serialize key. This means your snippet would look like:
$result = '1';
$this->set('theResult', $result);
$this->set('_serialize', array('theResult'));
I don't have the .json extension in the URL and the Router::parseExtensions('json'); line in my routes.php file, so the #dhofstet's answer did not work for me.
My solution was to add the renderAs() call:
public $components = array('RequestHandler');
public function my_ajax_action() {
// do something
$result = '1';
$this->set('result', $result);
$this->set('_serialize', array('result'));
$this->RequestHandler->renderAs($this, 'json');
}
You could create an element and render it.
function test() {
$this->autoRender = false;
$result = array('demo' => '1');
$this->set(compact('result'));
$this->set('_serialize', array('result'));
$this->render(DS.'Elements'.DS.'element_name');
}
See docs
The simplest way is this. Works well for me.
public function fun() {
$this->autoRender = false;
$this->request->onlyAllow('ajax');
$result = array('data1' => 'hello', 'data2' => 'world');
return json_encode($result);
}

How do I use Model in Helper - CakePHP 2.x

I recently upgraded my app from cake 1.3.x to cake 2.x. Now I have a helper which uses model in some function. Initially syntax for loading model was (working for 1.3.x)
App::import('Model', $modelName);
$modelObject = &ClassRegistry::getObject($modelName);
$modelObject->find()
Now I changed it to following
App::uses($modelName,'Model');
$modelObject = &ClassRegistry::getObject($modelName);
$modelObject->find()
Problem is, this conversion is not working. Can anybody tell me where am I doing wrong. Thanking in advance.
PS:
Error message is:
Call to a member function find() on a non-object
working code should be
//let $modelName be User
App::import("Model", "User");
$model = new User();
$model->find("list");
I hope this will help some needy fellow
You can also load model in helper, add following method in helper class:
Step1:
public function loadModel($modelClass = null, $id = null) {
if ($modelClass === null) {
$modelClass = $this->modelClass;
}
$this->uses = ($this->uses) ? (array) $this->uses : array();
if (!in_array($modelClass, $this->uses, true)) {
$this->uses[] = $modelClass;
}
list($plugin, $modelClass) = pluginSplit($modelClass, true);
$this->{$modelClass} = ClassRegistry::init(array(
'class' => $plugin . $modelClass, 'alias' => $modelClass, 'id' => $id
));
if (!$this->{$modelClass}) {
throw new MissingModelException($modelClass);
}
return true;
}
Step2: call above method as you do in controller like this:
$this->loadModel(ModelName);
I hope this would resolve problem
I wanna go through helper to view data In the form of foreach
public function display()
{
$links = TableRegistry::getTableLocator()->get('category');
$category = $links->find('all')
->where(['status' => 1, 'position' => 0])
->select([
"category" => 'parent', 'name'
])
->toArray();
return $category['category'];
}

CakePHP While-loop inside another loop

Since I'm in need of my navigation buttons I've placed the following code inside my AppController since i need it on every page.
// app/Controller/AppController.php
class AppController extends Controller {
public $uses = array('Categorie');
public function beforeFilter()
{
$parents = $this->Categorie->find('all', array('conditions' => array('cat_parent' => 0)));
$childs = $this->Categorie->find('threaded', array('conditions' => array('cat_parent' => $parents['Categorie']['cat_id'])));
echo '<pre>'.var_dump($parents).'</pre>';
}
}
I don't think this is the good way too accomplish what I want.. how can i do a while inside a while with the CakePHP Framework.
Kind Regards,
Jordy
You don't need a while loop in this case, you could just find the categories where cat_parent is not zero:
$childs = $this->Categorie->find('threaded', array(
'conditions' => 'cat_parent != 0'
));

using user defined variable in model class variable in cakephp

I want to use a form variable inside a cakephp model class variable $actsAs.Below is an example code.
public $actsAs = array('MeioUpload' => array('doc' => array('allowedMime' => array('application/x-compressed','application/x-zip-compressed','application/zip','multipart/x-zip'),'dir'=>'uploads'.DS.$this->data['User']['foldername'])));
In the above code i have used a form variable ($this->data['User']['foldername']) in the $actsAs array for passing directory name to meioupload behaviour.
What can be the write process to implement it.
That definition is wrong.
You can set that data from the constructor though.
public function __construct($data) {
$this->actsAs = array('MeioUpload' => array('doc' => array('allowedMime' => array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), 'dir' => 'uploads' . DS . $data['User']['foldername'])));
}
Something like that would do the trick.
I added parent::__construct(); And $this->Behaviors->init($this->alias,$this->actsAs); and it works good.
Below is the modified code:
public function __construct() {
parent::__construct();
$this->actsAs = array('MeioUpload' => array('doc' => array('allowedMime' => array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'), 'allowedExt' => array('.zip'),'dir' => 'uploads' . DS . $_REQUEST['data']['User']['foldername'])));
$this->Behaviors->init($this->alias,$this->actsAs);
}
In this example I’m changing path dynamically from controller.
CODE :
In Controller ( Where you specifying data to change value of $actsAs variable ) :
$custom_path=’/img/cakephp’;
Configure::write(‘path_var’,$custom_path);
In Model where you’ll change value in constructor :
public function __construct($id = false, $table = null, $ds = null)
{
$path = Configure::read(‘path_var’);
// change actsAs’s different value according to your need
$this->actsAs['Upload.Upload']['photo']['path'] = $path;
parent::__construct($id, $table, $ds);
}
Please write statement Configure::write before model created.

Resources