Long time lurking first time posting, I am stumped!
I have been attempting to get a dynamic category list on my employers eBay shop for a while now, I have spent a lot of time trawling for answers or pre-written code but came to the conclusion that if I want it done I'm going to have to do it myself (totally fine but time consuming).
Playing with the eBay Dev API testing ground I have managed to pull down the categories that I want. What I am finding difficult is how to then style and organize the results.
This would be easier if I could target the tags that the XML outputs with CSS but as they are non-standard, I can't.
This is what I have written so far, the 'style color:red' was simply to test the div was working and all the required credentials are stored in the 'keys.php' file:
<?php
/* © 2013 eBay Inc., All Rights Reserved */
/* Licensed under CDDL 1.0 - http://opensource.org/licenses/cddl1.php */
require_once('keys.php') ?>
<?php require_once('eBaySession.php') ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<TITLE>GetCatagories</TITLE>
<style type="text/css">
#child {
color:red;
}
</style>
</HEAD>
<BODY>
<?php
//SiteID must also be set in the Request's XML
//SiteID = 3 (US) - UK = 3, Canada = 2, Australia = 15, ....
//SiteID Indicates the eBay site to associate the call with
$siteID = 3;
//the call being made:
$verb = 'GetStore';
//Level / amount of data for the call to return (default = 0)
$detailLevel = 0;
///Build the request Xml string
$requestXmlBody = '<?xml version="1.0" encoding="utf-8" ?>';
$requestXmlBody .= '<GetStoreRequest xmlns="urn:ebay:apis:eBLBaseComponents">';
$requestXmlBody .= "<RequesterCredentials><eBayAuthToken>$userToken</eBayAuthToken></RequesterCredentials>";
$requestXmlBody .= '</GetStoreRequest>';
//Create a new eBay session with all details pulled in from included keys.php
$session = new eBaySession($userToken, $devID, $appID, $certID, $serverUrl, $compatabilityLevel, $siteID, $verb);
//send the request and get response
$responseXml = $session->sendHttpRequest($requestXmlBody);
if(stristr($responseXml, 'HTTP 404') || $responseXml == '')
die('<P>Error sending request');
//Xml string is parsed and creates a DOM Document object
$responseDoc = new DomDocument();
$responseDoc->loadXML($responseXml);
//get any error nodes
$errors = $responseDoc->getElementsByTagName('Errors');
//if there are error nodes
if($errors->length > 0)
{
echo '<P><B>eBay returned the following error(s):</B>';
//display each error
//Get error code, ShortMesaage and LongMessage
$code = $errors->item(0)->getElementsByTagName('ErrorCode');
$shortMsg = $errors->item(0)->getElementsByTagName('ShortMessage');
$longMsg = $errors->item(0)->getElementsByTagName('LongMessage');
//Display code and shortmessage
echo '<P>', $code->item(0)->nodeValue, ' : ', str_replace(">", ">", str_replace("<", "<", $shortMsg->item(0)->nodeValue));
//if there is a long message (ie ErrorLevel=1), display it
if(count($longMsg) > 0)
echo '<BR>', str_replace(">", ">", str_replace("<", "<", $longMsg->item(0)->nodeValue));
}
else //no errors
{
$i = 2;
while ($i <= 188) {
echo '<div id="catagories">';
echo $responseDoc->getElementsByTagName("Name")->item($i++)- >textContent;
echo '<BR>';
echo '</div>';
}
}
?>
</BODY>
</HTML>
The majority of the above code is credential checking and error management it's really the last 12 or so lines of code that do the heavy lifting.
Currently it has output all of my categories and the corresponding child categories in one long vertical list, ideally I would like to indent the children and give them a smaller font-size, the easiest way (to my mind) would have been to div them out and apply CSS but I'm beginning to think there is an easier way, any suggestions or comments are welcome at this point,
Thank you for any help in advance
If you are happy to use Composer in your project I have developed an SDK for PHP that simplifies using the API. The example below will get the store categories in the correct order and output a simple tree using nested <ol> elements which can be styles using CSS.
<?php
require __DIR__.'/vendor/autoload.php';
use \DTS\eBaySDK\Constants;
use \DTS\eBaySDK\Trading\Services;
use \DTS\eBaySDK\Trading\Types;
use \DTS\eBaySDK\Trading\Enums;
$service = new Services\TradingService([
'credentials' => [
'appId' => $appID,
'devId' => $devID,
'certId' => $certID
],
'authToken' => $userToken,
'siteId' => Constants\SiteIds::GB
]);
$request = new Types\GetStoreRequestType();
$request->CategoryStructureOnly = true;
$response = $service->getStore($request);
$html = '';
if (isset($response->Errors)) {
$html .= '<p>eBay returned the following error(s):<br/>';
foreach ($response->Errors as $error) {
$html .= sprintf(
"%s: %s<br/>%s<br/>",
$error->SeverityCode === Enums\SeverityCodeType::C_ERROR ? 'Error' : 'Warning',
htmlentities($error->ShortMessage),
htmlentities($error->LongMessage)
);
}
$html .= '</p>';
}
if ($response->Ack !== 'Failure') {
$categories = iterator_to_array($response->Store->CustomCategories->CustomCategory);
usort($categories, 'sortCategories');
foreach ($categories as $category) {
$html .= '<ol>'.buildCategory($category).'</ol>';
}
}
function buildCategory($category)
{
$html = '<li>';
$html .= htmlentities($category->Name);
$children = iterator_to_array($category->ChildCategory);
usort($children, 'sortCategories');
foreach ($children as $child) {
$html .= '<ol>'.buildCategory($child).'</ol>';
}
$html .= '</li>';
return $html;
}
function sortCategories($a, $b)
{
if ($a->Order === $b->Order) {
return 0;
}
return ($a->Order < $b->Order) ? -1 : 1;
}
echo <<< EOF_HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
<style>
ol {
list-style-type: none;
}
</style>
</head>
<body>
$html
</body>
</html>
EOF_HTML;
Related
I created an HTML application form for my employer so that applicant's can apply online. However, I'm running into some issues with the PHP bit. I'd like for it to send me an email containing ALL of the forms field names along with their values (even if the value is left blank). It needs to be in this specific format so that I can quickly 'convert' that data programmatically from the email into an HCL Notes form.
However, when a checkbox on my HTML form is left unchecked, it is not sent to the $_POST array at all, which then obviously ends up breaking the bit that converts it as it can't find the correct field names.
I know this is a strange and very specific issue, but does anyone have any ideas as to how I can go about this successfully?
My PHP code currently (removed the parameters at the top for privacy):
<?php session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Results</title>
</head>
<body>
<?php
//--------------------------Set these paramaters--------------------------
// Subject of email sent to you.
$subject = '';
// Your email address. This is where the form information will be sent.
$emailadd = '';
// Where to redirect after form is processed.
$url = '';
// Makes all fields required. If set to '1' no field can not be empty. If set to '0' any or all fields can be empty.
$req = '0';
$time = time();
// --------------------------Do not edit below this line--------------------------
$text = "Results from form:\n\n";
$space = ' ';
$line = '
';
include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
$securimage = new Securimage();
if ($securimage->check($_POST['captcha_code']) == false) {
// handle the error accordingly with your other error checking
// or you can do something really basic like this
die('The code you entered was incorrect. Go back and try again.');
}
foreach ($_POST as $key => $value)
{
if ($key != "captcha_code"){
$j = strlen($key);
if ($j >= 40){echo "Name of form element $key cannot be longer than 39 characters";die;}
$j = 40 - $j;
for ($i = 1; $i <= $j; $i++)
{$space .= ' ';}
$value = str_replace('\n', "$line", $value);
$conc = "{$key}:$space{$value}$line";
$text .= $conc;
$space = ' ';
}
}
$text .= 'END OF APPLICATION';
mail($emailadd, $subject, $text, 'From: ');
echo '<script>alert("Application successfully submitted.");</script>';
echo '<META HTTP-EQUIV=Refresh CONTENT="0; URL='.$url.'">';
?>
</body>
</html>
Here's how the emails look, I need it to be just like this but with ALL fields regardless of if they have values or not:
Create an array that lists all the fields that should be in the email. Then instead of looping through $_POST, loop through that array. Display the corresponding $_POST field if it's filled in, otherwise show a blank value.
$fields = ['ReasonForReferral', 'FirstName', 'MiddleName', ...];
foreach ($fields as $field) {
$conc .= "$field: " . (isset($_POST[$field]) ? str_replace($_POST[$field], "\n", $line) : '') . $line;
}
Here i want to do read the xl file in php,here i displayed all datas that means in xl file i have four columns called Title,Url,Visitors,Accesses.but for me don't want like this , i want only title name how can do this ? View my answer
<?php
include 'excel_reader.php'; // include the class
// creates an object instance of the class, and read the excel file data
$excel = new PhpExcelReader;
$excel->read('test.xls');
function sheetData($sheet) {
$re = '<table>'; // starts html table
$row = 1;
while($row <= $sheet['numRows']) {
$re .= "<tr>\n";
$column = 1;
$cell = isset($sheet['cells'][$row][1]) ? $sheet['cells'][$row][1] : '';
$re .= " <td>$cell</td>\n";
$re .= "</tr>\n";
$row++;
}
return $re .'</table>';// ends and returns the html table
}
$nr_sheets = count($excel->sheets);// gets the number of sheets
$excel_data = ''; // to store the the html tables with data of each sheet
// traverses the number of sheets and sets html table with each sheet data in $excel_data
for($i=0; $i<$nr_sheets; $i++) {
//$excel_data .= '<h4>Sheet '. ($i + 1) .' (<em>'. $excel->boundsheets[$i]['name'] .'</em>)</h4>'. sheetData($excel->sheets[$i]) .'<br/>';
$excel_data .= sheetData($excel->sheets[$i]) .'<br/>';
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example PHP Excel Reader</title>
<style type="text/css">
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 0 0.5em;
}
</style>
</head>
<body>
<?php
// displays tables with excel file data
echo $excel_data;
?>
</body>
</html>
By observing the $sheet array you will get Title at the position of 4,1 as follows.
By changing this line as shown
$cell = isset($sheet['cells'][4][1]) ? $sheet['cells'][4][1] : '';
But it looks like you have copied this code from somewhere. It is hard to identify your need and modify it. Change the code as per your requirement and if any error occurs then post your question on SO
as per your requirement your sheetData function should be like this
function sheetData($sheet) {
$re = '<table>'; // starts html table
$x = 1;
while($x <= $sheet['numRows']) {
$re .= "<tr>\n";
$cell = isset($sheet['cells'][$x][1]) ? $sheet['cells'][$x][1] : '';
if($cell != 'Title'){ // check for title here
$re .= " <td>$cell</td>\n";
$re .= "</tr>\n";
}
$x++;
}
return $re .'</table>'; // ends and returns the html table
}
I am new to api's and ebays api. What i am trying to do is select items from a spacific store on ebay (http://stores.ebay.com/Nu-Tek-Sales : or userID : machinre_nuteksalesparts)
Currently it grabs 3 random items of off ebay. I think that I am using the wrong variable for the userID b/c if i set it to anything, I get the same results. Any help in the right direction would be nice. Thank you
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Merchandising Tutorial Sample</title>
<style type="text/css">body { font-family: arial,sans-serif; font-size: small; } </style>
</head>
<body>
<?php
// Turn on all errors, warnings and notices for easier PHP debugging
error_reporting(E_ALL);
// Define global variables and settings
$m_endpoint = 'http://svcs.ebay.com/MerchandisingService?'; // Merchandising URL to call
$appid = 'My-account-ID'; // You will need to supply your own AppID
$responseEncoding = 'XML'; // Type of response we want back
// Create a function for the getMostWatchedItems call
function getMostWatchedItemsResults ($selectedItemID = '', $cellColor = '') {
global $m_endpoint;
global $appid;
global $responseEncoding;
// Construct getMostWatchedItems call with maxResults and categoryId as input
$apicalla = "$m_endpoint";
$apicalla .= "OPERATION-NAME=getMostWatchedItems";
$apicalla .= "&SERVICE-VERSION=1.0.0";
$apicalla .= "&CONSUMER-ID=$appid";
$apicalla .= "&RESPONSE-DATA-FORMAT=$responseEncoding";
$apicalla .= "&maxResults=3";
$apicalla .= "&userID=machinre_nuteksalesparts";
// Load the call and capture the document returned by eBay API
$resp = simplexml_load_file($apicalla);
// Check to see if the response was loaded, else print an error
if ($resp) {
// Set return value for the function to null
$retna = '';
// Verify whether call was successful
if ($resp->ack == "Success") {
// If there were no errors, build the return response for the function
$retna .= "<h1>Top 3 Most Watched Items in the ";
$retna .= $resp->itemRecommendations->item->primaryCategoryName;
$retna .= " Category</h1> \n";
// Build a table for the 3 most watched items
$retna .= "<!-- start table in getMostWatchedItemsResults --> \n";
$retna .= "<table width=\"100%\" cellpadding=\"5\" border=\"0\"><tr> \n";
// For each item node, build a table cell and append it to $retna
foreach($resp->itemRecommendations->item as $item) {
// Determine which price to display
if ($item->currentPrice) {
$price = $item->currentPrice;
} else {
$price = $item->buyItNowPrice;
}
// For each item, create a cell with imageURL, viewItemURL, watchCount, currentPrice
$retna .= "<td valign=\"bottom\"> \n";
$retna .= "<img src=\"$item->imageURL\"> \n";
$retna .= "<p>" . $item->title . "</p>\n";
$retna .= 'Watch count: <b>' . $item->watchCount . "</b><br> \n";
$retna .= 'Current price: <b>$' . $price . "</b><br><br> \n";
$retna .= "</td> \n";
}
$retna .= "</tr></table> \n<!-- finish table in getMostWatchedItemsResults --> \n";
} else {
// If there were errors, print an error
$retna = "The response contains errors<br>";
$retna .= "Call used was: $apicalla";
} // if errors
} else {
// If there was no response, print an error
$retna = "Dang! Must not have got the getMostWatchedItems response!<br>";
$retna .= "Call used was: $apicalla";
} // End if response exists
// Return the function's value
return $retna;
} // End of getMostWatchedItemsResults function
// Display the response data
print getMostWatchedItemsResults('', '');
?>
</body>
</html>
userID is not a valid input for the getMostWatchedItems call.
Instead, you will need to use FindItemsAdvanced and use an item filter for seller ID. See
http://developer.ebay.com/Devzone/finding/CallRef/findItemsAdvanced.html
and
http://developer.ebay.com/Devzone/finding/CallRef/types/ItemFilterType.html
you could use the getSellerList call within the trading api, here an ready to test example:
https://ebay-sdk.intradesys.com/s/c0c7c76d30bd3dcaefc96f40275bdc0a
you can also generate the php code for this call by clicking on "retrieve php code"
i'm having a code for simple php crawler that fetches all the html pages from websites upto depth 5 but if ,I run that for getting all the data contained in a div tag with its id like [container, main ,wrapper.etc] then it show unexpected result...heres the php code ::
<?php
$a=$_POST['t1'];
function crawl_page($url, $depth = 5)
{
static $seen = array();
if (isset($seen[$url]) || $depth === 0) {
return;
}
$seen[$url] = true;
$dom = new DOMDocument('1.0');
#$dom->loadHTMLFile($url);
$anchors = $dom->getElementsByTagName('div');
foreach ($anchors as $element) {
$href = $element->getAttribute('id');
//$href = $element->find('div[id=main]', 0)->plaintext;
if (0 !== strpos($href, 'main')) {
$host = "http://".parse_url($url,PHP_URL_USER);
$href = $host. '/' . ltrim($href, '/');
}
crawl_page($href, $depth - 1);
}
echo "New Page:<br /> ";
echo "URL:",$url,PHP_EOL,"<br />","CONTENT:",PHP_EOL,$dom->saveHTML(),PHP_EOL,PHP_EOL," <br /> <br />";
}
crawl_page($a, 5);
?>
this code is working good for anchor tags but i want this working for div tag only that fetches all the data contained in it nothing else. i want this for my project if anybody has done that then helpme out.......the html code is written down
<HTML>
<head>
<title></title>
</head>
<body>
<form method="POST" action="crawler1edit[2].php">
Enter Url:-<input type="text" name="t1">
<input type="submit" value="send" name="s1">
</form>
</body>
</HTML>
in action attribute crawler1edit[2].php is the php file containing php code written at the top
Is there a reason why you aren't just targeting the divs by ID ?
$dom->getElementById ("main");
I have php code for list all ".swf" files in a folder. (The name of the files is always:
"99-dd-mm-YY_HH-mm-ss.swf", example: "01-19-06-2011_18-40-00.swf".
When I have more than 500 files in the folder is complicated to see and to refresh the page.
I need paginate the list of files.
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title></title>
<script type="text/javascript">
function submitform()
{
document.myform.submit();
}
</script>
</head>
<body>
<form name="myform" action="some.php" method="post">
<?php
echo "\n<br>\n";
echo "<a href='javascript:this.location.reload();' style='color: #000000; font-weight: normal'>Refresh</a></br>";
echo "<tr>\n<td>\n<a href='javascript:javascript:history.go(-1)'>\n";
echo "<img src='../../inc/img/back.png' alt='Back'";
echo " border=0>\n";
echo "<b> Back</b></a></td>\n";
echo "\n</tr>\n";
echo "\n<br>\n\n<br>\n";
$folder='.';
function order($a,$b){
global $folder;
$directory='.';
return strcmp(strtolower($a), strtolower($b));
}
$folder=opendir($folder);
while($files=readdir($folder)){
$ext = pathinfo($files, PATHINFO_EXTENSION);
if ($ext == 'swf') { //con esta línea saco el nombre index.php del listado
$file[]=$files;
usort($file, "order");
}
}
$n = 0;
foreach($file as $archiv){
$n = $n + 1;
$day = substr($archiv, 3,10);
$day = str_replace("-","/", $day);
$hour = substr($archiv, 14,8);
$hour = str_replace("-",":", $hour);
echo "<img alt='Ver $archiv' src='../../inc/img/video.png'> Video $n, Día: $day, hour: $hour\n ";
echo "<input type='submit' name='xxx' value='$archiv'></td>\n";
echo "\n</tr>\n";
echo "<br>";
}
closedir($folder);
echo "\n<br>\n";
echo "<tr>\n<td>\n<a href='javascript:javascript:history.go(-1)'>\n";
echo "<img src='../../inc/img/back.png' alt='Back'";
echo " border=0>\n";
echo "<b> Back</b></a></td>\n";
echo "\n</tr>\n";
?>
</form>
</body>
</html>
When required to go through lots of folders and files, try the Iterator object. A nice example:
function get_files($dir)
{
$dir = new DirectoryIterator($dir);
$list = iterator_to_array($dir, false);
return array_slice($list, 2);
}
This will get all the file names (if you have php 5.3 or higher) very fast and will do the if dir_exists / file_exists for you! The array_slice so it removes the . and .. directory.
I used this code for simple pagination
<?php
// Include the pagination class
include 'pagination.class.php';
// Create the pagination object
$pagination = new pagination;
// some example data
foreach (range(1, 100) as $value) {
$products[] = array(
'Product' => 'Product '.$value,
'Price' => rand(100, 1000),
);
}
// If we have an array with items
if (count($products)) {
// Parse through the pagination class
$productPages = $pagination->generate($products, 20);
// If we have items
if (count($productPages) != 0) {
// Create the page numbers
echo $pageNumbers = '<div>'.$pagination->links().'</div>';
// Loop through all the items in the array
foreach ($productPages as $productID => $productArray) {
// Show the information about the item
echo '<p><b>'.$productArray['Product'].'</b> 243'.$productArray['Price'].'</p>';
}
// print out the page numbers beneath the results
echo $pageNumbers;
}
}
?>
Here there is pagination class and the example for download:
http://lotsofcode.com/php/php-array-pagination.htm
Thanks for all!
Like #Tessmore said, Spl Iterators are teh awesomesauce. According to the docs, you only need PHP > 5.1 for the basic iterators.
Cross-posting an example --
DirectoryIterator and LimitIterator are my new best friends, although glob seems to prefilter more easily. You could also write a custom FilterIterator. Needs PHP > 5.1, I think.
No prefilter:
$dir_iterator = new DirectoryIterator($dir);
$paginated = new LimitIterator($dir_iterator, $page * $perpage, $perpage);
Glob prefilter:
$dir_glob = $dir . '/*.{jpg,gif,png}';
$dir_iterator = new ArrayObject(glob($dir_glob, GLOB_BRACE));
$dir_iterator = $dir_iterator->getIterator();
$paginated = new LimitIterator($dir_iterator, $page * $perpage, $perpage);
Then, do your thing:
foreach ($paginated as $file) { ... }
Note that in the case of the DirectoryIterator example, $file will be an instance of SplFileInfo, whereas glob example is just the disk path.