PHP Simple HTML Dom Parser count specific results? - php

Right now i am working around one PHP script based on http://simplehtmldom.sourceforge.net/.
Here is my code:
<?PHP
foreach ($html->find('li.tooltip') as $ul) {
$id = $ul->id;
$dt = "data-text";
$dt = "data-text";
$cid = "colvar-id";
$datatext = $ul->$dt;
$colvarid = $ul->$cid;
$countN = count($id);
$number = 1;
$N = $i++;
if ($N == "") {
$N = 0;
}
}
?>
<?PHP echo "Result is: $countN"; ?>
This code is suposed to count the number of founded occurencies, but it displays nothing.
All i want is to count the founded occurencies and simply display the number of occurencies.
Thanks in advance!

You can use count():
$html = str_get_html(<<<EOF
<ul>
<li>not a tooltip</li>
<li class="tooltip">tooltip</li>
<li class="tooltip">also a tooltip</li>
</ul>
EOF
);
echo count($html->find('li.tooltip'));
// 2

Related

Loop through xml nodes with simplexml

Im trying to create a table of Jobs on my site, pulling info from an xml feed I have access to... I've looked at various examples online and videos but I can't seem to understand how it works. My xml feed returns the following node structure:
<OutputVacancyAsXml>
<Vacancy>
<VacancyID></VacancyID>
<Job></Job>
<ClosingDate></ClosingDate>
</Vacancy>
</OutputVacancyAsXml>
I've had success with pulling through one item with this code:
<?php
$x = simplexml_load_file('https://www.octopus-hr.co.uk/recruit/OutputVacancyAsXml.aspx?CompanyID=400-73A3BCA1-D952-4BA6-AADB-D8BF3B495DF6');
echo $x->Vacancy[5]->Job;
?>
But converting it to foreach seems to be where I'm struggling. Heres the code I have tried so far with no luck;
<?php
$html = "";
$url = "https://www.octopus-hr.co.uk/recruit/OutputVacancyAsXml.aspx?CompanyID=400-73A3BCA1-D952-4BA6-AADB-D8BF3B495DF6";
$xml = simplexml_load_file($url);
for ($i = 0; $i < 10; $i++) {
$title = $xml->OutputVacancyAsXml->Vacancy[$i]->job;
$html .= "<p>$title</p>";
}
echo $html;
?>
Thanks all :)
Taken from the documentation
Note:
Properties ($movies->movie in previous example) are not arrays. They
are iterable and accessible objects.
With that kept in mind you can simple run over the nodes with foreach
$xml = simplexml_load_file($url);
foreach ($xml->OutputVacancyAsXml->Vacancy as $vacanacy)
{
echo (string)$vacanacy->Job; // Echo out the Job Title
}
Ok looks like I found a solution. Heres the code that worked for me plus it contains a little bit of code that pulls out duplicated (it was displaying each item 4 times!)...
<?php
$x = simplexml_load_file('https://www.octopus-hr.co.uk/recruit/OutputVacancyAsXml.aspx?CompanyID=400-73A3BCA1-D952-4BA6-AADB-D8BF3B495DF6');
$num = count($x->Vacancy);
//echo "num is $num";
$stopduplicates = array();
for ($i = 0; $i < $num; $i++) {
$job = $x->Vacancy[$i]->Job;
$closingdate = $x->Vacancy[$i]->ClosingDate;
// http://stackoverflow.com/questions/416548/forcing-a-simplexml-object-to-a-string-regardless-of-context
$vacancyid = (string) $x->Vacancy[$i]->VacancyID;
if (!in_array($vacancyid, $stopduplicates)) {
echo '
<tr class="job-row">
<td class="job-cell">'.$job.'</td>
<td class="date-cell">'.$closingdate.'</td>
<td class="apply-cell">
Apply Here
</td>
</tr>';
}
$stopduplicates[] = $vacancyid;
} //print_r($stopduplicates);
?>

separating categories with Filemaker api / php

I'm stuck on a massive project I'm helping with- we have a FileMaker database and I've created an online catalogue for it. Originally we just had clothing and it worked perfectly, but now we're adding other collections as well. I'm trying to make just the the "C" (clothing) collection show up below, but it's not working. I'm new to the FileMaker api so help is greatly appreciated.
<?php
/*the function that displays the buttons (the img) of each dress to link to the details page*/
function displayRecords($records){
/*TO DO*/
foreach ($records as $record){
$photo = $record->getField("Photo");
$thumbnail = $record->getField("Thumbnail");
$date = $record->getField("Date CR");
$tNum = $record->getField("Catalog_Number");
$category = $record->getField("Collection");
if ($category = "C"){
echo ("<div class=\"dimg\">");
echo ("<a href = \"http://fadma.edu/historicalcollection/museum/details_test_textiles.php?id=");
echo($tNum);
echo ("\">");
echo ("<img src= \" ");
echo ($thumbnail);
echo (" \"></a>");
echo ("<div class=\"desc\">");
echo ($date);
echo ("</div></div>");}
}
}
$begin = (int)$_GET["begin"];
$end = (int)$_GET["end"];
for ($x = $begin; $x <= $end; $x++){
$findCommand = $fm->newFindCommand("Listing");
$findCommand->addFindCriterion("Photo", "*");
$findCommand->addFindCriterion("Date CR", $x);
$result = $findCommand->execute();
if(FileMaker::isError($result)){
continue;
}
$records = $result->getRecords();
displayRecords($records);
}
?>
I typically use fx.php for querying Filemaker but after a quick look at your code you seem to be filtering the results with the following:
if ($category = "C"){
However the single = is an assignment operator, not a comparison operator. You will want to check if $category is equal to C, not set $category to C.
Try using if ($category == "C"){ instead. Note the double ==

PHP - Assign some class to li tag based on some condition inside loop

I have following Two-dimensional array:
$data = array
(
array("1.2"),
array("2.5"),
array("4.7"),
array("5.7"),
array("3.5"),
array("7.2"),
array("4.7"),
array("3.5")
);
Now I am displaying my records through loop:
<ul>
<?php
for($i=0; $i<count($data); $i++):
?>
<li><?php echo $data[$i][0]; ?></li>
<?php
endfor;
?>
</ul>
and this is the result:
Now I want to check some condition inside loop and add class="red" to li.
Example 1:
If 4.7 found inside the loop, add class="red" to next all li tags.
Example 2:
If 3.5 found inside the loop, add class="red" to next all li tags.
Example 3:
If 5.7 found inside the loop, add class="red" to next all li tags.
Any idea how to add class to li tags when some condition match.
Thanks.
You can just switch on the class as soon as a matching item is found.
$switch_value = '4.7'; // set the value where you want to switch colors
$class = ''; // initialize the class to empty string
foreach ($data as $value) {
echo "<li$class>$value[0]</li>";
// set the class to red the first time the value is found
if ($value[0] == $switch_value) $class = ' class="red"';
}
It's important to set the class after echoing the list item to get the output you want.
You can do it this way:
<ul>
<?php
$class = ''; $num = 4.7;
for($i=0; $i<count($data); $i++):
?>
<li class='<?php echo $class; ?>'><?php echo $data[$i][0]; ?></li>
<?php
if( $data[$i][0] == $num ) $class = 'red';
endfor;
?>
</ul>
Just change the $num to desired value programmatically.
Edit: move the if block to end of for block to leave the number's occurrence.
Just check a condition with a value, and assign it
<ul>
<?php
$isRed = false;
$value_to_search = 3.5;
for($i=0; $i<count($data); $i++):
?>
<li class="<?php echo ($isRed == true)?'redClass':'';"><?php echo $data[$i][0]; ?></li>
<?php
if($data[$i][0] == $value_to_search )
$isRed = true;
endfor;
?>
</ul>
I guess you can use something like:
<ul>
<?php
$red = false;
for($i=0; $i<count($data); $i++){
if($data[$i][0] == "3.5" or $data[$i][0] == "4.7" or $data[$i][0] == "5.7" or $red){
echo "<li class=\"red\">{$data[$i][0]}</li>";
$red = true;
}else{
echo "<li>{$data[$i][0]}</li>";
}
}
?>
</ul>
Output:
<ul><li>1.2</li><li>2.5</li><li class="red">4.7</li><li class="red">5.7</li><li class="red">3.5</li><li class="red">7.2</li><li class="red">4.7</li><li class="red">3.5</li></ul>
Ideone Demo
http://ideone.com/s2gdmG

Php add class dynamically to the first and last block

I have an array like this
$products_array = array('test product', 'test new product', 'test lipsum', 'test lorem', ....);
I just got the values from array like this
echo '<ul>';
foreach( $products_array as $product_array ) {
echo '<li>$product_array</li>';
}
echo '</ul>';
But here I want something dynamic. I want to add class name according to the value set by the user. Lets say user wants to show 5 lists in a row then the markup will be like this
<ul>
<li class="first">test product</li>
<li>test new product</li>
<li>test lipsum</li>
<li>test lorem</li>
<li class="last">test update</li>
<li class="first">test new product</li>
<li>test a product</li>
<li>test new lipsum</li>
<li>test lorem</li>
<li class="last">test new update</li>
</ul>
So here you can see at last means after each 5 post its adding class last and it is adding class first to the first list and after the fifith list blocks. So in this when user will set $class = 3 then it will add last class to the third block and the first will be added to the first and the list block just after the 3rd, 6th, 9th etc
I have done like this
$last = '4' //set 4. so for 4th,8th,12th it will add class last. and for 1st, 5th, 9th it will add class first
echo '<ul>';
$i = 0;
$count = count($products_array);
foreach( $products_array as $product_array ) {
$i++;
$class = '';
if( $i == $count ) {
$class = 'last';
}
echo '<li class='.$class.'>$product_array</li>';
}
echo '</ul>';
But its not working. So can somone tell me how to do this? Any help and suggestions will be really appreciable. Thanks
Use a modulus to determine the class to add. The logic goes...
When the remainder is 0, we are on the last item of each group (the nth of n)
When the remainder is 1, we are on the first item of each group (the 1st of n)
Otherwise, we are somewhere in the middle
For example
$last = 4;
?>
<ul>
<?php
foreach ($products_array as $index => $product) :
switch(($index + 1) % $last) { // array indexes are 0-based so add 1
case 0 :
$class = 'last';
break;
case 1 :
$class = 'first';
break;
default :
$class = '';
}
?>
<li class="<?= $class ?>"><?= htmlspecialchars($product) ?></li>
<?php endforeach ?>
</ul>
eval.in demo
This should do the trick. You could also use modulus, but i am not quite sure how it behaves with small perPage-settings.
//your perPage-setting, change this for more elements per page
$perPage = 3;
$count = count($products_array);
//loop over elements
for($i = 1; $i <= $count; $i++) {
$className = "";
if($i / $perPage == 0) {
$className = "last";
} else if((floor($i / $perPage) * $perPage + 1 == $i)
$className = "first";
echo '<li class='.$className.'>'.$product_array[$i-1].'</li>';
}

Limit results in PHP using while loop

I have a list of returned subcategories. I only have access to the template display and not to the MySQL query so no, I can't limit the query.
Right now all the results are returned. I would like to limit the list to 5, and then add a "more" link if there are more than 5 results.
I know I did this wrong because I don't think count is actually tied to the foreach:
<ul class="sub-categories">
<?php
while (count($category->getChildren()) <= 5) { // line I added for while loop
foreach ($category->getChildren() as $child) {
if (!$child->totalItemCount())
continue;
$link = $this->app->route->category($child);
$item_count = ($this->params->get('template.show_sub_categories_item_count')) ? ' <span>('.$child->totalItemCount().')</span>' : '';
echo '<li>'.$child->name.''.$item_count.'</li>';
}
} // line I added for while loop
?>
</ul>
Keep track within the foreach and break; when you've reached the limit:
<ul class="sub-categories">
<?php
$i = 0;
foreach ($category->getChildren() as $child) {
if (!$child->totalItemCount()) continue;
$i++; if($i>5) break;
$link = $this->app->route->category($child);
$item_count = ($this->params->get('template.show_sub_categories_item_count')) ? ' <span>('.$child->totalItemCount().')</span>' : '';
echo '<li>'.$child->name.''.$item_count.'</li>';
}
?>
</ul>

Categories