I am pretty new to cakephp and I am banging my head against the wall trying to write a pretty basic statement.
In my view file, I want to say if the is_open column in the events table is true, echo something. If it is not true, echo something else.
<?php
if ($response['data']['Event']['is_open'] == true) {
echo "Yes";
} else {
echo "No";
}
?>
I am having trouble working backwards within the controller to get the data in the first place.
In my controller I have something this:
public function some_function() {
$events = $this->Event->find('all');
}
In my view file, I get this error:
Notice (8): Undefined index: Event [View/Applications/agreement.ctp, line 21]
Can anyone point out what I am doing wrong?
I have been going through the blog tutorial and it's clear in some places to me and not clear in others. Where I am still having trouble is displaying anything in the view.
After further reading I want to do something like this in the controller:
$myVariable = $this->Event->find('first',
array( 'fields' => 'Event.is_open ',
'conditions' => array('Event.id =' => '400') ));
What I am hoping to say is grab the is_open value from the events table where the events.id = 400 (later on this value will be dynamic) Does this look even remotely correct? – mmalv just now edit
How did you come up with $response['data']?
In your EventsController you correctly set the return of $this->Event->find('all') to $events. In order for this variable to be available to your view you need to call Controller::set on it like this:
$this->set('events', $events);
Or even simpler, in one step, you can just do:
$this->set('events', $this->Event->find('all'));
Then in your Event view (perhaps someplace like View/Events/index.ctp) access the variable by the name $events. It should be in the format
Array(
[0] => Array(
'Event' => Array(
'id' => 1,
'name' => 'An open name!',
'is_open' => true
)
),
[1] => Array(
'Event' => Array(
'id' => 1,
'name' => 'Another event but closed',
'is_open' => false
)
)
)
So now all you need in your view is to run a loop like:
foreach ($events as $key => $value) {
if ($value['Event']['is_open']) {
echo "Yes";
} else {
echo "No";
}
}
All this is thoroughly explained in the cookbook, just go through the blog tutorial.
Related
Cane Somebody give me an ideas on this Please!
I Generate multiple checkboxes from a table that is related with another table with HABTM relationship association.
I would like to generate multiple checkboxes with an image along with the text in the label.
My two tables are items and items_characteristics. So an Item HasAndBelongToMany characteristics, and an ItemCharacteristic HasAndBelongToMany Items.
echo $this->Form->input('Item.ItemCharacteristic',array(
'label' =>false,
'type'=>'select',
'multiple'=>'checkbox',
'options' => $itemCharacteristics ,
'selected' => $this->Html->value('ItemCharacteristic.ItemCharacteristic')
));
This code generate the list of the checkboxes properly and works perfect:
This is what i have:
Which is generated from DB from the table items_characteristics.
And this is what i wanna have:
Does Anyone have any Idea how i can achieve this Please?
I assume that in your controller you did something like:
$this->request->data = $this->Item->find('first', ... );
so that $data contains the information about selected characteristics in form of a subarray,
edit: I also assume that Item habtm ItemCharacteristic
then in your view
$checked_characteristics = Hash::extract($this->data, 'ItemCharacteristic.{n}.id');
foreach($itemCharacteristics as $id => $itemCharacteristic )
{
$checked = in_array($id, $checked_characteristics );
$img = $this->Html->image('cake.icon.png'); // put here the name
// of the icon you want to show
// based on the charateristic
// you are displayng
echo $this->Form->input(
'ItemCharacteristic.ItemCharacteristic.',
array(
'between' => $img,
'label' => $itemCharacteristic,
'value' => $id,
'type' => 'checkbox',
'checked' => $checked
)
);
}
edit: from your comment I understand that $itemCharacteristics come from a find('list') statement.
change it into a find('all', array('recursive' => -1));
now your code becomes
foreach($itemCharacteristics as $itemCharacteristic )
{
$id = $itemCharacteristic['ItemCharacteristic']['id'];
$icon_name = $itemCharacteristic['ItemCharacteristic']['icon_name']; //or wherever you get your icon path
$img = $this->Html->image($icon_name);
$itemCharacteristicName = $itemCharacteristic['ItemCharacteristic']['name'];
// same as above
}
How can I create a custom Rule-Action which will successfully save a value as a replacement pattern for use in the other actions?
I got some very good help here on retrieving Product-Display information from a Product-Order.
As I said, the linked answer helped a great deal but the returned path data for the Product-Display comes back in the http://www.mysite/node/77 format. However, I really just need the numeric value only so I can load the node by performing a Fetch entity by id action supplying the numeric value and publishing the Product-Display node etc.
So, I implemented a custom action which will take the Product-Display URL(node/77) and return 77.
I copied the Fetch entity by id code and modified it so my returned numeric value can be saved and used in other Actions. The code is below:
function my_custom_action_info(){
$actions['publish_product_display_node'] = array(
'label' => t('Fetch product-display id'),
'parameter' => array(
'type' => array(
'type' => 'uri',
'label' => t('My Action'),
'options list' => 'rules_entity_action_type_options2',
'description' => t('Specifies the product-display url.'),
),
),
'provides' => array(
'entity_fetched' => array('type' => 'integer', 'label' => t('Fetched entity')),
),
'group' => t('Entities'),
'access callback' => 'rules_entity_action_access',
);
return $actions;
}
function publish_product_display_node($path = null){
$parts = explode('node/', $path);
return $parts[1];
}
function rules_entity_action_type_options2($element, $name = NULL) {
// We allow calling this function with just the element name too. That way
// we ease manual re-use.
$name = is_object($element) ? $element->getElementName() : $element;
return ($name == 'entity_create') ? rules_entity_type_options2('create') : rules_entity_type_options2();
}
function rules_entity_type_options2($key = NULL) {
$info = entity_get_info();
$types = array();
foreach ($info as $type => $entity_info) {
if (empty($entity_info['configuration']) && empty($entity_info['exportable'])) {
if (!isset($key) || entity_type_supports($type, $key)) {
$types[$type] = $entity_info['label'];
}
}
}
return $types;
}
function rules_action_entity_createfetch_access2(RulesAbstractPlugin $element) {
$op = $element->getElementName() == 'entity_create' ? 'create' : 'view';
return entity_access($op, $element->settings['type']);
}
As I said I copied the modified code so I don't claim to thoroughly understand all the functions aside from publish_product_display_node.
My code modifications work as far as setting the Product-Display URL token as the argument and also setting an entity variable label(Display NID) and value(display_nid).
The problem is when I check display_nid in newly created actions, the value is empty.
I need help figuring out the how to successfully save my entity value so I can use it in following Actions.
in the function publish_product_display_node, can you verify that you don't need to be returning $parts[0], instead of $[parts[1]?
It's just that Drupal paths are frequently in the form 'node/7' or 'taxonomy/term/6', and if you explode with 'node/' as the separator, you'd only have a single value which would start at index 0 for nodes...
So, just wondering if that would solve your issue...
Hi I'm currently working on a project and was wondering if it was possible to do two find functions in cakephp?
For example I am making a sports news website and I am grouping the news articles as top story, understory and headline.
What I want to do is retrive top stories so i can highlight these as the prominent story and then understory will be beneath as a lesser story and then headlines will be the least important.
This is what I have so far
function latestnews() {
$articles = $this->Article->find('all',
array('limit' =>3,
'order' =>
array('Article.date_created' => 'desc')));
if(isset($this->params['requested'])) {
return $articles;
}
$this->set('articles', $articles);
$articler = $this->Article->find('all',
array('Article.type' => 'topstory',
'Limit' => '1'
));
$this->set('articles', $articler);
}
however this doesn't seem to work, it doesn't limit the $articles function but instead echos all the data in the table.
in the view im doing a standard foreach statement to echo the data and I get thrown a undefined variable error.
Is what i am saying even possible or should I create different functions and then use them as elements?
Thanks for any input in advance!
You can bind the associationship with itself dynamically. Try this code:
function latestnews() {
$this->Article->bindModel(array('hasMany' => array('TopStory' => array('className' => 'Article',
'foreignKey' => false,
'conditions' => array('Article.type' => 'topstory')
),
'Highlight' .....
)));
$articles = $this->Article->find('all',
array('limit' =>3,
'order' => array('Article.date_created' => 'desc')));
if(isset($this->params['requested'])) {
return $articles;
}
$this->set('articles', $articles);
$articler = $this->Article->find('all',
array('Article.type' => 'topstory',
'Limit' => '1'
));
$this->set('articles', $articler);
}
Hope it will work for you.
#Arun Nope that didn't seem to work, I get this error, Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Article.type' in 'where clause' also I've tried to put it in an element with its own function and I then get thrown this error...
Notice (8): Undefined variable: data [APP/View/Elements/Articles/topstories.ctp, line 5]
Warning (2): Invalid argument supplied for foreach() [APP/View/Elements/Articles/topstories.ctp, line 5]
Notice (8): Undefined property: View::$Paginator [CORE/Cake/View/View.php, line 806]
Fatal error: Call to a member function prev() on a non-object in /Applications/XAMPP/xamppfiles/htdocs/kickoff/app/View/Elements/Articles/topstories.ctp on line 21
The controller code is the following...
function topstories() {
$this->paginate = array(
'conditions' => array('Article.type' => 'topstory'),
'limit' => 2,
'order' => array(
'date_created' => 'asc'
)
);
$data = $this->paginate('Article');
$this->set(compact('data'));
}
I find this error confusing as if I don't put this in an element and in a view instead it works perfectly! however in an element not so perfect :S
any ideas as to why this is the case??
Instead of using two find methods in one function I instead chose to simply create different functions and use them as elements for example...
function premiershiptopstory() {
$pltopnews = $this->Article->find('all', array(
'conditions' => array('Article.league' => 'premiership',
'Article.type' => 'topstory')));
if(!empty($this->request->params['requested'])) {
return $pltopnews;}
$this->set('article', $pltopnews);
}
However in the view you must request the action otherwise you will get thrown an error, to request the action simply use this line of code...
<?php $pltopnews = $this->requestAction('/Articles/premiershiptopstory');
Hope this helps others!
I am trying to retrieve the id of a record in my database in the index() method of my cns_controller.php file. I want to use it for a find(). However, the $this->Cn->id is not returning a value, therefore the find() doesn't work either.
$uses = array('Cn', 'Release');
/*check non-null value in released_user_id,
showing Release tab has been signed off*/
$releaseSignedOff = $this->Release->find('all', array(
'conditions' => array('Release.cn_id =' => $this->Cn->id,
'Release.released_user_id !=' => null)
));
(sizeof($releaseSignedOff) > 0) ? $releaseSignedOff = true : $releaseSignedOff = false;
$this->set('releaseSignedOff', $releaseSignedOff);
Any ideas?
Thanks
I ended up not using my index view, instead I looked up the most recent record in my cns database table and redirected to the view view using the returned value as a parameter:
if (!$id) {
$most_recent_change_note = $this->Cn->find('first', array(
'order' => array('Cn.id DESC')
));
$this->redirect(array('controller' => 'cns',
'action' => 'view/'.$most_recent_change_note['Cn']['id']));
}
For the pagination, I ended up using the $neighbors feature of CakePHP:
function get_neighbors($id) {
$neighbors = $this->Cn->find('neighbors', array('field' => 'id',
'value' => $id));
$this->set('neighbors', $neighbors);
}
Then in my view view, I used those values to create links:
<div class="paging">
<?php echo ($neighbors['next']) ? $html->link('<< Prev',
array('controller'=>'cns',
'action'=>'view/'.$neighbors['next']['Cn']['id'])).' | ' : '<< Prev | ';
echo $html->link('Next >>', array('controller'=>'cns',
'action'=>'view/'.$neighbors['prev']['Cn']['id'])); ?>
</div>
Thanks to Charles and Ross for helping me reach this conclusion. :)
I'm using the Cupcake Forum plugin within CakePHP. There's a form for selecting the desired posts, and then submitting the form to delete the posts. The form data is apparently being sent to the 'moderate' function within the 'topics' controller using POST and GET methods simultaneously. The function first checks to see if the data sent in is POST. However, when the data is received, it shows that it's GET. A fellow programmer and I don't want to completely change someone else's internal code, but we can't figure out how the data is being sent by both methods and being received as GET. The code from the plugin is below:
--------------moderate.ctp (view)---------------------
<?php echo $form->create('Post', array('url' => array('controller' => 'topics', 'action' => 'moderate', $topic['Topic']['slug']))); ?>
-------------topics_controller.php (controller)-------
public function moderate($id) {
if ($this->RequestHandler->isGet()){
$this->log('Is GET!');
}
$user_id = $this->Auth->user('id');
$topic = $this->Topic->getTopicForViewing($id, $user_id, 'id');
// Access
$this->Toolbar->verifyAccess(array(
'exists' => $topic,
'permission' => $topic['ForumCategory']['accessRead'],
'moderate' => $topic['Topic']['forum_category_id']
));
$this->log('ID: '.$id.'\n');
if ($this->RequestHandler->isPost()){
$this->log('Is POST!');
}
if ($this->RequestHandler->isGet()){
$this->log('Is GET!');
}
$this->log($this->RequestHandler->getReferer());
$this->log(serialize($this->data));
// Processing
if ($this->RequestHandler->isPost()) {
$this->log('INSIDE POST!');
if (!empty($this->data['Post']['items'])) {
$items = $this->data['Post']['items'];
$action = $this->data['Post']['action'];
foreach ($items as $post_id) {
$this->log('Action: '.$action.'\n');
$this->log('PostID: '.$post_id.'\n');
if (is_numeric($post_id)) {
if ($action == 'delete') {
$this->Topic->Post->destroy($post_id);
$this->Session->setFlash(sprintf(__d('forum', 'A total of %d post(s) have been permanently deleted', true), count($items)));
}
}
}
}
}
We added the log checks, which show the result of 'Is GET!' in Cake's log file. Since the method is GET, the statement 'if ($this->RequestHandler->isPost())' is never true; therefore, the submitted posts aren't deleted. What are we missing?
Try changing moderate.ctp to
<?php
echo $form->create('Post', array(
'url' => array(
'controller' => 'topics',
'action' => 'moderate',
$topic['Topic']['slug'],
),
'type' => 'post',
));
?>