Retreving specific index from array in CakePHP - php

I have an array and I would to break it up with out using a foreach loop. I have a query like this:
$pending = $this->Article->find('all', array(
'conditions' => array('Article.status' => 'pending'),
'order' => array('Article.created' => 'desc'), 'limit' =>5
));
Now this brings me back the most recent 5 articles. What I would normally do here is just loop through them and display them, but I want to grab the specific fields for each index separately. How exactly do I do this?
I assumed it was something like:
<?php
echo $this->Html->link($pending['Article'['title'],array('controller'=>
'articles','action'=>'view',$pending['Article']['id'][0]));?>
Where I just add the index to the end of the field I want for that specific element. This doesn't return the right data. How can I do this?
UPDATE:
I was able to figure this out, to grab the specific index from an array in cakephp, you just put the index after your array variable so in this case it would be:
<?php
echo $this->Html->link($pending[0]['Article'['title'],array('controller'=>
'articles','action'=>'view',$pending[0]['Article']['id']));?>
This will go the the numbered index and allow you to grab any part of the array you would like.

Related

Accessing Array Item Within Array With Same Name in PHP

I have a simple PHP array inside an array which looks like this:
$defaults = array(
"color" => "White",
array(
"color" => "0000CC",
)
)
The problem becomes when I want to call the second color item--since they are both named the same, I can't figure out how to access the SECOND color item on the command line. This command line code below doesn't work because it only gets the FIRST color item in the first array.
php /Users/me/temp/the_Script/create.php --color='0000CC'
How do I access that SECOND color item in the second array on the command line? Can I even grab both of them in the same command line arguments?
Thanks!
You can access like this:
$defaults[0]["color"]
This is because when you create an associative array they don't have index number, so when you create the second array inside the defaults array, PHP assign that to the first position.
In this particular case
$defaults = array( "color" => "White", array( "color" => "0000CC", ) );
var_dump($defaults[0]['color']);
But you're better off giving it an association
$defaults = array( "color" => "White", "codes" => array( "color" => "0000CC", ) );
var_dump($defaults['codes']['color']);
The general structure of your array doesn't make any sense to me though. I don't know if that's because you're just using it as an example or if you need to rethink the structure.

Cakephp: Saving the array value not the integer

After filtering some data, i created a variable $customers. This variable is a simple array
which has the following values:
array(
(int) 1 => 'Customer1',
(int) 2 => 'Customer2',
(int) 3 => 'Customer3'
)
I passed this array from the controller to the view like this
$this->set('customers', $customers);
In the view i use this array in a form so that the user can select one
echo $this->Form->input('customer_id', array('options' => array($customers)));
The data which is displayed in the select form is this 'Customer1', 'Customer2', 'Customer3'
Eveyting works ok so far.
Now, after the user has submited the data, i want to do some further logic in the controller. I want to take the data which the user has selected and save it in a second table. So i do this:
$this->Invoice->set('secondtabel', $this->request->data['Invoice']['customer_id']);
The data is being saved in the second table, but the problem is saves the value '1', '2', '3' not the name of the customer. How can i save the name of the customer and not the identifier number from the array.
Please bear with me, i am new to cakephp and to php in general.
I assume this is actually a problem with your HTML, your select box likely looks something like this:
<select name="customer_id">
<option value="1">Customer1</option>
<option value="2">Customer2</option>
<option value="3">Customer3</option>
</select>
This is why your values are 1, 2 or 3 and not Customer1 etc, because $this->request->data['Invoice']['customer_id'] is equal to 1, 2 or 3 etc.
My suggestion would be to fix this at the root of the problem, and I think that by only passing the values into your select box, you should get HTML like this:
<option>Customer1</option>
... which will mean that $this->request->data['Invoice']['customer_id'] will equal Customer1 etc.
So, try this: (array_values will return an array only containing the values, essentially stripping the keys)
$this->set('customers', array_values($customers));
This should fix your problem. However, as far as structured data goes, the way you are currently doing it (storing 1, 2 or 3 etc) is actually the correct way to do this. This way, you simply join the customers table when you are retrieving this data, and you can grab the name that way... Something like this:
$invoices = $this->Invoice->find('all', array(
'conditions' => array(
// your custom find conditions
),
'joins' => array(
array(
'table' => 'customers',
'alias' => 'Customer',
'type' => 'LEFT',
'conditions' => array('Customer.id = Invoice.customer_id')
)
),
'fields' => array(
'Invoice.*', // retrieve regular invoice data
'Customer.name' // retrieve the joined customer name too
)
));
This way you still store a customer ID as an integer, and simply look up the name with SQL when you go to retrieve that data.
A possible reason why you might want to do it simply by storing the customer's name as text is that you want to store the customers name as it appears at the time, meaning if it changes in the future, previous invoices with that name attached won't change with it because that name is stored in text rather than a numeric reference to another table containing a name that has changed.
Hope this helps.
Docs
http://php.net/array_values

Counting nested comments in the loop

While looping in get_comments() with these args:
$args = array(
'status' => 'approve',
'order' => 'DESC',
'number' => 5
);
I get more than five comments in the loop because of the nested comments.
I want to get the recent 5 comments even if they are parent or nested without disabling the nested feature from the admin panel.
For example: if the parent comment has 4 nested comments, i wanna just get it with it's nested and counted as 5 instead of counting other parents.
You could use array_slice to return the first 5 items from the returned wordpress array of comments:
$yourArray = $returnedCommentsArray;
$commentData= array_slice($yourArray, 0, 5)
Where returnedCommentsArray is the array of comments that is returned from your original wordpress call.

Pagination using multiple searcing criteria in codeigniter

Im trying to implement pagination using multiple searching criteria.
Supposed I Have student table. I also use pagination when the list of student displayed.
The pagination link is. site_url . '/student/page/'; so I use $config['uri_segment'] = 1;
so the pagination link will be
1
2
and son.
After that I wanna search student data using 3 searching criteria implemented using textfield.
id name address.
user can search by id or name or address or combination of the three criteria.
the url become
http://mysite/index.php/student/page/0
href=http://mysite/index.php/student/page/1
and son.
but I use get method for searching. and while trying to search using the search criteria field the url become
href="http://mysite/index.php/student/page/1?id=1&name=a&address=b
the problem occurred when I try create pagination based on criteria. because the pagination link have contain query string
i don't know how to create become
href="http://mysite/index.php/student/page/0?id=1&name=a&address=b
href="http://mysite/index.php/student/page/1?id=1&name=a&address=b
or do you have a best practice to solve this problem ?
Hi phill ....
I have try your suggestion.
$array = array('id' => '001', 'name' => 'a', 'address' => 'canada');
the url become
id/001/name/a/address/canada. I use $this->uri->uri_to_assoc() function to get key and value of the segment.
array (
id => 001,
name=>a,
address=>canada
)
but while there some searching criteria that not included while searching. let say, the user only search by name and address. the array become
$array = array('id' => '', 'name' => 'a', 'address' => 'canada'); and the url id/name/a/address/canada
the assoc array become
array (
id => name,
a=>address,
canada=>
)
the assoc array is not disorganized again. so I can't get the right value of the assoc array.
I think i will set the identifier to the searching criteria if not included. supposed i put #.
if isset($_GET['id']) then
$id = '#'
else
$id = $_GET['id']
$array = array('id' => $id, 'name' => 'a', 'address' => 'canada');
How about that ... ? or if there are another best practice ?
For that I would use $this->uri->uri_to_assoc():
index.php/user/search/name/joe/location/UK/gender/male
Using this function you can turn the
URI into an associative array with
this prototype:
[array]
(
'name' => 'joe'
'location' => 'UK'
'gender' => 'male'
)
See the full documentation here.
You can still use page/1 as the first lot then have /name/whatever afterwards.
Actualy, we can create pagination with multiple and unlimited criteria. Read here http://dengkul.com/2010/07/08/codeigniter-pagination-with-multiple-unlimited-searching-criteria/

Code Separation Paradox: Create HTML Tree from Multi-Dimensional Array AND Keep the HTML Outside of the Recursive Function

This working code seems to be the typical solution to this problem.
It takes a multi-dimensional array that holds categories and their subcategories (with no implied limitation on how many levels deep it goes) and creates an HTML unordered list from it, echoing it out onto the page from inside a recursive function.
Sub-levels are traversed by passing the value for each array element's 'children' key to array_walk() recursively, from inside the original callback function named _category_list()_.
How can this method of output be modified so that all HTML code would exist in the template, outside the function?
Here's the rundown of the code:
This multi-dimensional array holds the multi-level category tree.
Important keys to use in the HTML are 'category_id', 'name', and 'children'. Other keys have been purged from the array below for simplicity sake, but if they are useful they are: 'parent_id' and 'level' (starting with level 1).
<?php
// the array containing the tree
$categories = array (
'category_id' => '2',
'name' => 'Top Category Name',
'children' => array (
0 => array (
'category_id' => '188',
'name' => 'Category Name',
'children' => array (
0 => array (
'category_id' => '159',
'name' => 'Category Name',
'children' => array (),
),
1 => array (
'category_id' => '160',
'name' => 'Category Name',
'children' => array (),
),
2 => array (
'category_id' => '166',
'name' => 'Category Name',
'children' => array (),
),
),
),
1 => array (
'category_id' => '4',
'name' => 'Category Name',
'children' => array (
0 => array (
'category_id' => '141',
'name' => 'Category Name',
'children' => array (),
),
1 => array (
'category_id' => '142',
'name' => 'Category Name',
'children' => array (),
),
),
),
),
)
?>
.
This next function produces the majority of the HTML output, but it locks the HTML inside itself.
However, instead of echoing it right from the function, I'm looking for a way to pass this data back to the view template in a manner that is friendly for designers to customize.
<?php
// separate the HTML from this function,
// passing $v to the view template for handling
function category_list($v, $k){
switch ($k) {
case 'category_id':
echo "<li id="$v">";
break;
case 'name':
echo "$v";
break;
case 'children':
if(count($v) > 0){
echo "<ul>";
foreach($v as $k=>$v)
array_walk($v, 'category_list');
echo "</ul>";
}
echo "</li>";
break;
}
}
?>
.
The next block of code is the current template html/php with the call to traverse the first level of the array via array_walk() and referencing the recursive function above. The function itself then handles the recursion and iteration of deeper categories with 1 or more child. Of course, this is the typical approach.
This code should have all HTML tags, rather than just the outer tags.
<ul>
<?php array_walk($tree,'category_list'); ?>
</ul>
.
The Ideal Solution:
The end goal here is to find a way for template designers to create their ideal navigation structure without having to create or modify the recursion function (which isn't accessible), nor require use of a foreach loop for each level of the multi-dimensional array. The solution should not be tied to any specific depth limitations.
Examples of HTML customizations could range from placing additional attributes inside the ul/li tags, or even wrapping new tags around the output text, such as span tags, which are commonly used in navigations to achieve a sliding-doors effect with CSS. So I think the appropriate solution will need to support those case scenarios at a minimum.
Iterating through the array from the template using array_walk() would still be okay, as long as it can be used in such a way that the callback function passes the desired vars back to the template for use with the designer's HTML.
Ideally, if array_walk_recursive() knew how many levels deep its iterator actually is, I think this feat would be much easier to solve. But unless someone knows a workaround to that issue, the solution may be different entirely.
I also want to avoid using javascript methods of building the tree. And if there's a way to avoid using the switch, I'm open to suggestions there too.
Have you thought of writing a Class that manages and stores the info you want to pass back. You function could alter an instance of that class as it goes though and in the end pass back the filled object.
Your content would be encapsulated inside the class and you can write all the methods and utilities for the user to manipulate and output the data. Utility methods can also be written inside the class to show the number of levels, etc.
I haven't tried it myself but this is where I would start since the Class allows me to refine and expand on what my users would want and they wouldn't need to know the internal details of what was happening.

Categories