PHP DOMXPath query to return value - php

I want to get and show the title, tel, fax and address if they exist.
HTML code could be like :
<div id="id1">
<div class="AB">
<ul>
<li class="title"> AGENCE X </li>
<li class="tel"> 060000000</li>
<li class="fax"> 06000000</li>
<li class="address> this is the address </li>
</ul>
</div>
<div class="AB"> //the same class name
<ul>
<li class="titre"> AGENCE X </li>
<li class="tel"> 060000000</li>
<li class="fax"> 06000000</li>
</ul>
</div>
<div>...</div>
</div>
I wrote this code but I didn't know how to write the condition "if a node with class name 'address' or 'fax' or 'tel' exist' then do X.
Here is my code:
$doc = new DOMDocument();
#$doc->loadHTMLFile('http://website.com');
$node = $doc->getElementsByTagName('div') ;
$xpath=new DOMXPath($doc);
$titre=$xpath->query('//div/ul/li[#class="titre"]');
$adresse=$xpath->query('//div/ul/li[#class="adresse"]');
$phone=$xpath->query('//div/ul/li[#class="phone"]');
$fax=$xpath->query('//div/ul/li[#class="fax"]');
$a=0;$b=0;$c=0;
for($i=0;$i<$titre->length;$i++)
{
echo $titre->item($i)->nodeValue.'<br/>' ;
if(a "li" has classe="adresse" existe)
{ for($a=0;$a<$adresse->length;$a++)
{
echo $adresse->item($a)->nodeValue.'<br/>' ;
$a++;
}
}
if(a "li" has classe="titre" existe){ for($b=0;$b<$phone->length;$b++)
{
echo $titre->item($b)->nodeValue.'<br/>' ;
$b++;
}
}
if(a "li" has classe="fax" existe) { for($c=0;$c<$fax->length;$c++)
{
echo $fax->item($c)->nodeValue.'<br/>' ;
$c++;
}
}
}
Could someone tell me how can I would write this condition or another solution?

Related

creating class active dynamically in php

I am creating a menu dynamically based on the categories registered on the dataBase, What I need is:
When someone click in the link, this option should have the css class 'active', showing in with page the user is and even the pages are created dynamically.
I have no idea how to do this because I am php student and I couldn't find this information in google for "Dynamically menus" Thank you very much.
<nav class="menu">
<ul class="list">
<li class="line"><a id="item" href="index.php">Home</a></li>
<?php
$categories = $db->select("select * from tbl_category");
if($categories){
while ($result = $categories->fetch_assoc()){
echo <<<HTML
<li id="line" ><a class="item" href="categories.php?category=$result[id]">$result[name]</a></li>
HTML;
}
}
?>
</ul>
<nav>
First of all, you're looping through that while loop and adding the id of "line" to each and every <li> element. I suggest you create unique id's for each list item. I don't necessary advocate using the code the way you have it, just as an example, here's your code edited to do just that:
if($categories){
$i = 1;
while ($result = $categories->fetch_assoc()){
$i++;
echo <<<HTML
<li id="line$i" ><a class="item" href="categories.php?category=$result[id]">$result[name]</a></li>
HTML;
}
}
Then when someone clicks on your link, just use jQuery with something like this:
$(".item").click(function() {
$(this).parent('li').addClass('active');
});
Try something like that:
<nav class="menu">
<ul class="list">
<li class="line"><a id="item" href="index.php">Home</a></li>
<?php
$current_page = isset($_GET['category']) ? $_GET['category']: -1;
$categories = $db->select("select * from tbl_category");
if($categories){
while ($result = $categories->fetch_assoc()){
echo '<li id="line">';
if($result['category'] === $current_page) {
// If we're currently in the active page then add the active class to the <a>
echo '<a class="item active" href="categories.php?category='. $result[id] .'">';
} else {
echo '<a class="item" href="categories.php?category='. $result[id] .'">';
}
echo $result['name'];
echo '</a>';
echo '</li>';
}
}
?>
</ul>
<nav>
Thank you all for help, based on your code, I solved doing this:
menu.php:
<nav class="menu" id="menu">
<ul id="list" class="list">
<li id="line" class="<?php if($presentPage == '0')echo 'active';?>"><a id="item" class="item" href="index.php">Home</a></li>
<?php
function checked($pp, $id){
if($pp == $id){
$status = 'active';
return $status;
}
}
$query = "select * from tbl_category";
$category = $db->select($query);
if($category){
while ($result = $category->fetch_assoc()){
echo "
<li id='line' class='".checked($presentPage, $result['id'])."'><a id='item' class='item' href='categories.php?category=".$result['id']."'>".$result['name']."</a></li>
";//end echo
}//end while
}//end if
?>
</ul>
</nav>
In my index.php:
<?php $presentPage = 0;?>
<?php require_once 'header.php';?>
<?php require_once 'menu.php';?>
and in my categories.php:
<?php
if (!isset($_GET['category']) || $_GET['category'] == NULL) {
$presentPage = 0;
}else{
$presentPage = intval($_GET['category']);//just to make sure that the variable is a number
}
?>
<?php require_once 'header.php';?>
<?php require_once 'menu.php';?>
///...my code...
and in my CSS of course:
.active{
background: linear-gradient(#821e82, #be5abe);
}
Thats is working perfectly for me, Thank for all help.

need better PHP script for an if else condition to select current menu item

Using the following PHP script to select the page Im currently on.
each page has the variable $page== 'pagename'
This script works fine but sometimes the buttons need to be rolled over twice in order for the dropdown menu to appear.
Is there a better way?
<div id="navigation">
<ul id="nav">
<!-- If the button HOME is selected then make the HOME Button Active -->
<?php if ($page == 'home') { ?><li>HOME</li>
<?php } else { ?><li>HOME<?php } ?>
<!-- If the button ABOUT US is selected then make the ABOUT US Button Active -->
<?php if ($page == 'about-us') { ?><li>ABOUT US
</li>
<?php } else { ?><li>ABOUT US
</li>
<?php } ?>
<!-- If the page projects is selected then make the Projects Button Active -->
<?php if ($page == 'projects') { ?><li>PROJECTS
<ul>
<li>Project 1</li>
<li>Project 2</li>
<li>Project 3</li>
<li>Project 4</li>
</ul>
</li>
<?php } else { ?><li>PROJECTS
<ul>
<li>Project 1</li>
<li>Project 2</li>
<li>Project 3</li>
<li>Project 4</li>
</ul>
</li>
<?php } ?>
<!-- If the page Capabilities is selected then make the Capabilities Button Active -->
<?php if ($page == 'capabilities') { ?><li>CAPABILITIES
<ul>
<li>Civil Works</li>
<li>Commercial Construction</li>
<li>Controlled Waste Management</li>
<li>Plant Hire</li>
</ul>
</li>
<?php } else { ?><li>CAPABILITIES
<ul>
<li>Civil Works</li>
<li>Commercial Construction</li>
<li>Controlled Waste Management</li>
<li>Plant Hire</li>
</ul>
</li>
<?php } ?>
<!-- If the page Careers is selected then make the Careers Button Active -->
<?php if ($page == 'careers') { ?><li>CAREERS</li>
<?php } else { ?><li>CAREERS
</li>
<?php } ?>
<!-- If the page Contact Us is selected then make the Contact Us Button Active -->
<?php if ($page == 'contactus') { ?><li>CONTACT US</li>
<?php } else { ?><li>CONTACT US
</li>
<?php } ?>
</ul>
<!-- Search Form -->
<div class="search-form">
<form method="get" action="#">
<input type="text" class="search-text-box" />
</form>
</div>
</div>
<div class="clear"></div>
</div>
<!-- Navigation / End -->
The second part could be smaller:
<?php if ($page == 'projects') { ?><li>PROJECTS <?php } else { ?> <li>PROJECTS <?php } ?>
<ul>
<li>Project 1</li>
<li>Project 2</li>
<li>Project 3</li>
<li>Project 4</li>
</ul>
</li>
So basically on which page your are on, that should have id="current"? This can be done the following way:
<?php
$selected = array($page => ' id="current"');
?>
...
<li><a href="index.php"<?php print $selected['home']; ?>></li>
<li><a href="about-us.php"<?php print $selected['about-us']; ?>>ABOUT US</a></li>
...
The array $selected will have one index which is the current page and the value will be id="current". So this value will be applied to the active page only.
However this will trigger an undefined index notice, but you won't need any ifs in your code.
If you are okay with a bit more complex structure you could do it like this and won't get notices.
<?php
$selected = array($page => ' id="current"');
?>
...
<li><a href="index.php"<?php print isset($selected['home'])?$selected['home']:''; ?>></li>
<li><a href="about-us.php"<?php print isset($selected['about-us'])?$selected['about-us']:''; ?>>ABOUT US</a></li>
...
Since you are basically doing the same thing over and over again, I'd suggest automating the whole thing anyway.
<?php
$naviPages = array(
array('name' => 'HOME', 'url' => 'index.php'),
array('name' => 'ABOUT US', 'url' => 'about-us.php'),
array('name' => 'PROJECTS' => 'url' => 'projects.php', 'children' => array(
array('name' => 'Project 1', 'url' => 'project-01.php'),
array('name' => 'Project 2', 'url' => 'project-02.php'),
)),
//...
);
//...
foreach ($naviPages as $naviPage) {
print '<li><a href="'.$naviPage['url'].'"';
if ($page == $naviPage['name'])
print ' id="active"';
print '>'.$naviPage['name'].'</a>';
if (isset($naviPage['children'])) {
print '<ul>';
foreach ($naviPage['children'] as $naviPageChild) {
print '<li>'.$naviPageChild['name'].'</li>';
}
print '</ul>';
}
print '</li>';
}
I would tend to stick the $page as a css class in your <body> tag or the navigation div. Then you can do just about everything else in pure css!
So for example, say you have this:
<div id="navigation" class="page-<?php echo $page ?>">
<ul id="nav">
<li class="nav-home">HOME
<li class="nav-about">ABOUT US</li>
Notice how the navigation div has the page name, and each menu item has a unique class name. Now all you have to do is use some CSS:
.page-home .nav-home,
.page-about .nav-about {
color: red; /** assuming you want your active/current menu item to be red **/
}
See how much cleaner that is?
Of course you can then extend this to show/hiding the sub-menus. Give your sub-menu <ul> tag a unique classname:
<li class="nav-projects">PROJECTS
<ul class="submenu sub-projects">
...
</ul>
And some CSS to control that:
.submenu {
display: none; /** Our default **/
}
.page-projects .sub-projects {
display: block; /** Show the projects sub-menu when you are on that page **/
}

jQuery sortable don't get order var

I have this js code
$("#sortable").sortable({
axis: 'y',
handle: '.fancybox',
update: function() {
var order = $('#sortable').sortable('serialize');
$("#sortable").load("inc/ajax/sortable/update2.php?"+order);
alert(order);
}
});
and I populate the list with php:
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $result)
{
$_SESSION['img'][]=$result['id_imag'];
$img[]="
<div class='highlight-3' width='100%'>
<li id='".$result['id_imag']."'>
<a class='fancybox' href='".$result['den_img']."' data-fancybox-group='gallery' title='Reian Imob' >
<img src='".$result['den_img']."' id='".$result['id_imag']."' ></a>
<a href='#' id='".$result['id_imag']."' class='del' onclick='delete_imag_mod(this);' >Delete</a>
</li>
</div>";
}
The html:
<ul class="gallery" id="sortable" style="background:#FCFCFC; width:100%">
<?php
$images=$db->select_images ($_POST['vid']);
if($nr_imag>0) {
foreach($images as $val)
{
echo $val;
}
}
?>
</ul>
The problem is: var order don't get the values. How can I fix it?
Your html code should look something like this:
<ul id="sortable">
<li id="li_first"> // here undercsore is mandatory
<div>some text</div>
</li>
<li id="li_second"> // here undercsore is mandatory
<div>some text</div>
</li>
</ul>
For more info check this link : http://api.jqueryui.com/sortable/#method-serialize

How to extract value form HTML section in PHP

I need to extract data from HTML page which looks like:
<li>
<h2>
<span>rss</span>AC Ajaccio</h2>
<div class="club-left">
<img src="http://medias.lequipe.fr/logo-football/35/60?CCH-13-40" width="60" height="60">
</div>
<div class="club-right">
<ul class="club-links">
<li><span class="plus"></span>
Fiche club
</li>
<li><span class="plus"></span>
Calendrier
</li>
<li><span class="plus"></span>Effectif
</li>
<li><span class="plus"></span>
Stats joueurs
</li>
<li><span class="plus"></span>
Stats club
</li>
</ul>
</div>
<div class="clubt hidden">35</div>
<div class="clear"></div>
</li>
I would like to extract in PHP the href value and the text of this part:
**Stats joueurs**
I use the following code, but there is something missing:
$elements = $xpath->query("//div[#id='Base']/ul/li");
if (!is_null($elements)) {
foreach ($elements as $element) {
$nodes = $element->childNodes;
foreach ($nodes as $node) {
if($node->nodeName!='#text'){
echo $node->nodeValue.";<br/>";
$stringData = trim($node->nodeValue).";";
}
}
}
UPDATE:
Try:
$elements = $xpath->query("//ul[#class='club-links']//a");
foreach ($elements as $element) {
echo $element->nodeValue." - ".$element->getAttribute("href")."<br/>";
}

xPath insert before and after - With DOM and PHP

I need to add a class to a HTML structure.
My class is called "container" and should start right after <div><ul><li></h4> (the child of ul and its simblings, not grandchilds) and should end right before the closing of the same element.
My whole code looks like this:
<?php
$content = '
<div class="sidebar-1">
<ul>
<li>
<h4>Title</h4>
<ul>
<li>Test</li>
<li>Test</li>
</ul>
</li>
<li>
<p>Paragraf</p>
</li>
<li>
<h4>New title</h4>
<ul>
<li>Some text</li>
<li>Some text åäö</li>
</ul>
</li>
</ul>
</div>
';
$doc = new DOMDocument();
$doc->loadHTML($content);
$x = new DOMXPath($doc);
$start_text = '<div class="container">';
$end_text = '</div>';
foreach($x->query('//div/ul/li') as $anchor)
{
$anchor->insertBefore(new DOMText($start_text),$anchor->firstChild);
}
echo $doc->saveXML($doc->getElementsByTagName('ul')->item(0));
?>
It works as far as i can add the class opening but not the closing element. I also get strange encoding doing this. I want the output to be the same encoding as the input.
The result should be
<div class="sidebar-1">
<ul>
<li>
<h4>Title</h4>
<div class="content">
<ul>
<li>Test</li>
<li>Test</li>
</ul>
</div>
</li>
<li>
<div class="content">
<p>Paragraf</p>
</div>
</li>
<li>
<h4>New title</h4>
<div class="content">
<ul>
<li>Some text</li>
<li>Some text åäö</li>
</ul>
</div>
</li>
</ul>
</div>
I couldn't find a more elegant way to reassign all children, so I guess this will do. I think it gets what you're after, though.
(NOTE: Code updated to reflect additional requirements in the comments.)
$doc = new DOMDocument();
$doc->loadHTML($content);
$x = new DOMXPath($doc);
foreach($x->query('//div/ul/li') as $anchor)
{
$container = $doc->importNode(new DOMElement('div'));
$container->setAttribute('class', 'container');
$next = $anchor->firstChild;
while ($next !== NULL) {
$curr = $next;
$next = $curr->nextSibling;
if (($curr->nodeName != 'h4')
|| ($curr->attributes === NULL)
|| ($curr->attributes->getNamedItem('class') === NULL)
|| !preg_match('#(^| )title( |$)#', $curr->attributes->getNamedItem('class')->nodeValue)
) {
$container->appendChild($anchor->removeChild($curr));
}
}
$anchor->appendChild($container);
}
As for character encoding, I've been messing with it for a while and it's a tricky issue. The characters display correctly when you load with loadXML() but not with loadHTML(). There's a workaround in the comments, but it ain't pretty. Hopefully some of the user comments will help you can find a usable solution.

Categories