I'm currently receiving this error
Parse error: syntax error, unexpected T_OBJECT_OPERATOR
Please Note:
I'm new to php.
All I have basically done is merge
http://phpir.com/part-of-speech-tagging and
http://tappetyclick.com/blog/2013/06/25/twitter-xml-feeds-are-back
any help would be greatly appreciated.
my overall goal is to be able to collect all twitter search results and classify each word by its world class (part of speech)
anyway here is my code:
<?
//WORDCLASS
class PosTagger {
private $dict;
public function __construct($lexicon) {
$fh = fopen($lexicon, 'r');
while($line = fgets($fh)) {
$tags = explode(' ', $line);
$this->dict[strtolower(array_shift($tags))] = $tags;
}
fclose($fh);
}
public function tag($text) {
preg_match_all("/[\w\d\.]+/", $text, $matches);
$nouns = array('NN', 'NNS');
$return = array();
$i = 0;
foreach($matches[0] as $token) {
// default to a common noun
$return[$i] = array('token' => $token, 'tag' => 'NN');
// remove trailing full stops
if(substr($token, -1) == '.') {
$token = preg_replace('/\.+$/', '', $token);
}
// get from dict if set
if(isset($this->dict[strtolower($token)])) {
$return[$i]['tag'] = $this->dict[strtolower($token)][0];
}
// Converts verbs after 'the' to nouns
if($i > 0) {
if($return[$i - 1]['tag'] == 'DT' &&
in_array($return[$i]['tag'],
array('VBD', 'VBP', 'VB'))) {
$return[$i]['tag'] = 'NN';
}
}
// Convert noun to number if . appears
if($return[$i]['tag'][0] == 'N' && strpos($token, '.') !== false) {
$return[$i]['tag'] = 'CD';
}
// Convert noun to past particile if ends with 'ed'
if($return[$i]['tag'][0] == 'N' && substr($token, -2) == 'ed') {
$return[$i]['tag'] = 'VBN';
}
// Anything that ends 'ly' is an adverb
if(substr($token, -2) == 'ly') {
$return[$i]['tag'] = 'RB';
}
// Common noun to adjective if it ends with al
if(in_array($return[$i]['tag'], $nouns)
&& substr($token, -2) == 'al') {
$return[$i]['tag'] = 'JJ';
}
// Noun to verb if the word before is 'would'
if($i > 0) {
if($return[$i]['tag'] == 'NN'
&& strtolower($return[$i-1]['token']) == 'would') {
$return[$i]['tag'] = 'VB';
}
}
// Convert noun to plural if it ends with an s
if($return[$i]['tag'] == 'NN' && substr($token, -1) == 's') {
$return[$i]['tag'] = 'NNS';
}
// Convert common noun to gerund
if(in_array($return[$i]['tag'], $nouns)
&& substr($token, -3) == 'ing') {
$return[$i]['tag'] = 'VBG';
}
// If we get noun noun, and the second can be a verb, convert to verb
if($i > 0) {
if(in_array($return[$i]['tag'], $nouns)
&& in_array($return[$i-1]['tag'], $nouns)
&& isset($this->dict[strtolower($token)])) {
if(in_array('VBN', $this->dict[strtolower($token)])) {
$return[$i]['tag'] = 'VBN';
} else if(in_array('VBZ',
$this->dict[strtolower($token)])) {
$return[$i]['tag'] = 'VBZ';
}
}
}
$i++;
}
return $return;
}
}
?>
<?php
//TWITTER
// Include the twitter oauth library for PHP (I put it in a subdirectory
require_once("lib/twitteroauth/twitteroauth.php");
// Init
define("CONSUMER_KEY", "mykeyhere");
define("CONSUMER_SECRET", "mykeyhere");
define("OAUTH_TOKEN", "mykeyhere");
define("OAUTH_TOKEN_SECRET", "mykeyhere");
$q='search term';
// Get an authorised connection to twitter
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET);
$content = $connection->get("search/tweets.json?q=".$q."&result_type=recent");
// Send the xml header
header("Content-Type: application/rss+xml; charset=ISO-8859-1");
$url = 'http://'.$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
$xml ="";
$xml.= '<!--?xml version="1.0" encoding="ISO-8859-1"?-->'.PHP_EOL;
$xml.= '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">'.PHP_EOL;
$xml.= ' <channel>'.PHP_EOL;
$xml.= '<title>'.$q.'</title>'.PHP_EOL;
$xml.= ' <description>Search results</description>'.PHP_EOL;
$xml.= '<link>'.$url.'</link>'.PHP_EOL;
$xml.= ' <atom:link href="'.$url.'" rel="self" type="application/rss+xml">'.PHP_EOL;
// Get the status
foreach ($content->statuses as $status) {
//wordclass
$statustext = $status->text;
$tagger = new PosTagger('lexicon.txt');
$tags = $tagger->tag($statustext);
// Build the tweet url as we don't get this in the status object
$url = 'http://twitter.com/'.$status->user->screen_name.'/status/'.$status->id_str;
$date = explode(' ', $status->created_at);
$xml.= ' <item>'.PHP_EOL;
$xml.= '<title>'.$status->text.'</title>'.PHP_EOL;
$xml.= ' <description>'.$tags->text.'</description>'.PHP_EOL;
$xml.= '<link>'.$url.'</link>'.PHP_EOL;
$xml.= ' <guid ispermalink="true">'.$url.'</guid>'.PHP_EOL;
// Format the date since the twitter format doesn't work for rss
$xml.= ' <pubdate>'.$date[0].', '.$date[2].' '.$date[1].' '.$date[5].' '.$date[3].' '.$date[4].'</pubdate>'.PHP_EOL;
// Get the attached media
/*
if ($status->entities) {
if (is_array($status->entities->media)) {
foreach ($status->entities->media as $media) {
switch ($media->type) {
//Currently only photo's supported but I suspected with vine video will be along soon
case 'photo':
$enc_type = 'image/jpeg';
break;
}
if (!empty($enc_type)) {
// We need the file size for the media so try to get this from the headers
$headers = get_headers($media->media_url);
$size = $headers['Content-Length'];
if (empty($size)) {
foreach ($headers as $header) {
$h = explode(':', $header);
if ($h[0] == 'Content-Length') {
$size = trim($h[1]);
break; // Found what we need, stop looping
}
}
}
if (empty($size)) {
$size = 1; //This is basically a hack to make the rss validate
}
$xml.= ' <enclosure length="'.$size.'" type="'.$enc_type.'" url="'.$media->media_url.'">'.PHP_EOL;
}
}
}
}
$xml.= ' </enclosure></item>'.PHP_EOL;*/
$xml.= ' </item>'.PHP_EOL;
}
$xml.= ' </atom:link></channel>'.PHP_EOL;
$xml.= '</rss>'.PHP_EOL;
// Return the xml for the rss
print $xml;
?>
the above code returns the following error
Parse error: syntax error, unexpected T_OBJECT_OPERATOR in /var/www/test/Twitter/index.php
for this line
$tags = new PosTagger('lexicon.txt')->tag($status->text);
Related
I need to refresh modifications after install module.
public function install() {
$this->load->controller('marketplace/modification/refresh');
}
I tried this. Its worked but the page redirected to modification listing. How can i do without redirect. I am using opencart 3.
If you don't want to edit modification.php or clone its refresh function, You can use this:
public function install(){
$data['redirect'] = 'extension/extension/module';
$this->load->controller('marketplace/modification/refresh', $data);
}
You could not controll by this way as you are doing:
You need to do this as
public function install() {
$this->refresh();
}
protected function refresh($data = array()) {
$this->load->language('marketplace/modification');
$this->document->setTitle($this->language->get('heading_title'));
$this->load->model('setting/modification');
if ($this->validate()) {
// Just before files are deleted, if config settings say maintenance mode is off then turn it on
$maintenance = $this->config->get('config_maintenance');
$this->load->model('setting/setting');
$this->model_setting_setting->editSettingValue('config', 'config_maintenance', true);
//Log
$log = array();
// Clear all modification files
$files = array();
// Make path into an array
$path = array(DIR_MODIFICATION . '*');
// While the path array is still populated keep looping through
while (count($path) != 0) {
$next = array_shift($path);
foreach (glob($next) as $file) {
// If directory add to path array
if (is_dir($file)) {
$path[] = $file . '/*';
}
// Add the file to the files to be deleted array
$files[] = $file;
}
}
// Reverse sort the file array
rsort($files);
// Clear all modification files
foreach ($files as $file) {
if ($file != DIR_MODIFICATION . 'index.html') {
// If file just delete
if (is_file($file)) {
unlink($file);
// If directory use the remove directory function
} elseif (is_dir($file)) {
rmdir($file);
}
}
}
// Begin
$xml = array();
// Load the default modification XML
$xml[] = file_get_contents(DIR_SYSTEM . 'modification.xml');
// This is purly for developers so they can run mods directly and have them run without upload after each change.
$files = glob(DIR_SYSTEM . '*.ocmod.xml');
if ($files) {
foreach ($files as $file) {
$xml[] = file_get_contents($file);
}
}
// Get the default modification file
$results = $this->model_setting_modification->getModifications();
foreach ($results as $result) {
if ($result['status']) {
$xml[] = $result['xml'];
}
}
$modification = array();
foreach ($xml as $xml) {
if (empty($xml)){
continue;
}
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->loadXml($xml);
// Log
$log[] = 'MOD: ' . $dom->getElementsByTagName('name')->item(0)->textContent;
// Wipe the past modification store in the backup array
$recovery = array();
// Set the a recovery of the modification code in case we need to use it if an abort attribute is used.
if (isset($modification)) {
$recovery = $modification;
}
$files = $dom->getElementsByTagName('modification')->item(0)->getElementsByTagName('file');
foreach ($files as $file) {
$operations = $file->getElementsByTagName('operation');
$files = explode('|', $file->getAttribute('path'));
foreach ($files as $file) {
$path = '';
// Get the full path of the files that are going to be used for modification
if ((substr($file, 0, 7) == 'catalog')) {
$path = DIR_CATALOG . substr($file, 8);
}
if ((substr($file, 0, 5) == 'admin')) {
$path = DIR_APPLICATION . substr($file, 6);
}
if ((substr($file, 0, 6) == 'system')) {
$path = DIR_SYSTEM . substr($file, 7);
}
if ($path) {
$files = glob($path, GLOB_BRACE);
if ($files) {
foreach ($files as $file) {
// Get the key to be used for the modification cache filename.
if (substr($file, 0, strlen(DIR_CATALOG)) == DIR_CATALOG) {
$key = 'catalog/' . substr($file, strlen(DIR_CATALOG));
}
if (substr($file, 0, strlen(DIR_APPLICATION)) == DIR_APPLICATION) {
$key = 'admin/' . substr($file, strlen(DIR_APPLICATION));
}
if (substr($file, 0, strlen(DIR_SYSTEM)) == DIR_SYSTEM) {
$key = 'system/' . substr($file, strlen(DIR_SYSTEM));
}
// If file contents is not already in the modification array we need to load it.
if (!isset($modification[$key])) {
$content = file_get_contents($file);
$modification[$key] = preg_replace('~\r?\n~', "\n", $content);
$original[$key] = preg_replace('~\r?\n~', "\n", $content);
// Log
$log[] = PHP_EOL . 'FILE: ' . $key;
}
foreach ($operations as $operation) {
$error = $operation->getAttribute('error');
// Ignoreif
$ignoreif = $operation->getElementsByTagName('ignoreif')->item(0);
if ($ignoreif) {
if ($ignoreif->getAttribute('regex') != 'true') {
if (strpos($modification[$key], $ignoreif->textContent) !== false) {
continue;
}
} else {
if (preg_match($ignoreif->textContent, $modification[$key])) {
continue;
}
}
}
$status = false;
// Search and replace
if ($operation->getElementsByTagName('search')->item(0)->getAttribute('regex') != 'true') {
// Search
$search = $operation->getElementsByTagName('search')->item(0)->textContent;
$trim = $operation->getElementsByTagName('search')->item(0)->getAttribute('trim');
$index = $operation->getElementsByTagName('search')->item(0)->getAttribute('index');
// Trim line if no trim attribute is set or is set to true.
if (!$trim || $trim == 'true') {
$search = trim($search);
}
// Add
$add = $operation->getElementsByTagName('add')->item(0)->textContent;
$trim = $operation->getElementsByTagName('add')->item(0)->getAttribute('trim');
$position = $operation->getElementsByTagName('add')->item(0)->getAttribute('position');
$offset = $operation->getElementsByTagName('add')->item(0)->getAttribute('offset');
if ($offset == '') {
$offset = 0;
}
// Trim line if is set to true.
if ($trim == 'true') {
$add = trim($add);
}
// Log
$log[] = 'CODE: ' . $search;
// Check if using indexes
if ($index !== '') {
$indexes = explode(',', $index);
} else {
$indexes = array();
}
// Get all the matches
$i = 0;
$lines = explode("\n", $modification[$key]);
for ($line_id = 0; $line_id < count($lines); $line_id++) {
$line = $lines[$line_id];
// Status
$match = false;
// Check to see if the line matches the search code.
if (stripos($line, $search) !== false) {
// If indexes are not used then just set the found status to true.
if (!$indexes) {
$match = true;
} elseif (in_array($i, $indexes)) {
$match = true;
}
$i++;
}
// Now for replacing or adding to the matched elements
if ($match) {
switch ($position) {
default:
case 'replace':
$new_lines = explode("\n", $add);
if ($offset < 0) {
array_splice($lines, $line_id + $offset, abs($offset) + 1, array(str_replace($search, $add, $line)));
$line_id -= $offset;
} else {
array_splice($lines, $line_id, $offset + 1, array(str_replace($search, $add, $line)));
}
break;
case 'before':
$new_lines = explode("\n", $add);
array_splice($lines, $line_id - $offset, 0, $new_lines);
$line_id += count($new_lines);
break;
case 'after':
$new_lines = explode("\n", $add);
array_splice($lines, ($line_id + 1) + $offset, 0, $new_lines);
$line_id += count($new_lines);
break;
}
// Log
$log[] = 'LINE: ' . $line_id;
$status = true;
}
}
$modification[$key] = implode("\n", $lines);
} else {
$search = trim($operation->getElementsByTagName('search')->item(0)->textContent);
$limit = $operation->getElementsByTagName('search')->item(0)->getAttribute('limit');
$replace = trim($operation->getElementsByTagName('add')->item(0)->textContent);
// Limit
if (!$limit) {
$limit = -1;
}
// Log
$match = array();
preg_match_all($search, $modification[$key], $match, PREG_OFFSET_CAPTURE);
// Remove part of the the result if a limit is set.
if ($limit > 0) {
$match[0] = array_slice($match[0], 0, $limit);
}
if ($match[0]) {
$log[] = 'REGEX: ' . $search;
for ($i = 0; $i < count($match[0]); $i++) {
$log[] = 'LINE: ' . (substr_count(substr($modification[$key], 0, $match[0][$i][1]), "\n") + 1);
}
$status = true;
}
// Make the modification
$modification[$key] = preg_replace($search, $replace, $modification[$key], $limit);
}
if (!$status) {
// Abort applying this modification completely.
if ($error == 'abort') {
$modification = $recovery;
// Log
$log[] = 'NOT FOUND - ABORTING!';
break 5;
}
// Skip current operation or break
elseif ($error == 'skip') {
// Log
$log[] = 'NOT FOUND - OPERATION SKIPPED!';
continue;
}
// Break current operations
else {
// Log
$log[] = 'NOT FOUND - OPERATIONS ABORTED!';
break;
}
}
}
}
}
}
}
}
// Log
$log[] = '----------------------------------------------------------------';
}
// Log
$ocmod = new Log('ocmod.log');
$ocmod->write(implode("\n", $log));
// Write all modification files
foreach ($modification as $key => $value) {
// Only create a file if there are changes
if ($original[$key] != $value) {
$path = '';
$directories = explode('/', dirname($key));
foreach ($directories as $directory) {
$path = $path . '/' . $directory;
if (!is_dir(DIR_MODIFICATION . $path)) {
#mkdir(DIR_MODIFICATION . $path, 0777);
}
}
$handle = fopen(DIR_MODIFICATION . $key, 'w');
fwrite($handle, $value);
fclose($handle);
}
}
// Maintance mode back to original settings
$this->model_setting_setting->editSettingValue('config', 'config_maintenance', $maintenance);
// Do not return success message if refresh() was called with $data
$this->session->data['success'] = $this->language->get('text_success');
$url = '';
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
if (isset($this->request->get['page'])) {
$url .= '&page=' . $this->request->get['page'];
}
}
}
I hope it shouwl work for you.
This process is used to refresh the modification when your module installing.
if you need globally this then please tell me I will update you process.
I'm trying to extract icecast metadata from streams.
I have code that works for some streams and not for others.
The issue is that some streams don't return the icymetaint value and that's where the code gets lost.
I can't get the icymetaint header from this stream:
http://radio.hbr1.com:19800/tronic.ogg
But when I put it in VLC media player it shows the meta just fine.
So what exactly am I missing here? What other ways are there for an icecast stream to transmit metdata? The stream version is Icecast 2.3.3
This is code inside a class to retrieve the metadata and headers:
public function GetDataFromStream($parsedUrl)
{
$returnData = array();
$addr = $parsedUrl['host'];
$addr = gethostbyname($addr);
$sock = fsockopen($addr, $parsedUrl['port'], $errno, $errstr, 5);
$path = isset($parsedUrl['path'])?$parsedUrl['path']:'/';
if ($sock)
{
$request = 'GET '. $path .' HTTP/1.0' . CRLF .
'Host: ' . $parsedUrl['host'] . CRLF .
'Connection: Close' . CRLF .
'User-Agent: ' . $this->useragent . CRLF .
'Accept: */*' . CRLF .
'icy-metadata: 1'.CRLF.
'icy-prebuffer: 65536'.CRLF.
(isset($parsedUrl['user']) ? 'Authorization: Basic ' .
base64_encode($parsedUrl['user'] . ':' . $parsedUrl['pass']) . CRLF : '').
'X-TipOfTheDay: Winamp "Classic" rulez all of them.' . CRLF . CRLF;
if (fwrite($sock, $request))
{
$theaders = $line = '';
while (!feof($sock))
{
$line = fgets($sock, 4096);
if('' == trim($line))
break;
$theaders .= $line;
}
$theaders = explode(CRLF, $theaders);
foreach ($theaders as $header)
{
$t = explode(':', $header);
if (isset($t[0]) && trim($t[0]) != '')
{
$name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0])));
array_shift($t);
$value = trim(implode(':', $t));
if ($value != '')
{
if (is_numeric($value))
$this->headers[$name] = (int)$value;
else
$this->headers[$name] = $value;
}
}
}
if (isset($this->headers['icymetaint']))
{
$metainterval = $this->headers['icymetaint'];
$intervals = 0;
$metadata = '';
while(1)
{
$data = '';
while(!feof($sock))
{
$data .= fgetc($sock);
if (strlen($data) >= $metainterval)
break;
}
$len = join(unpack('c', fgetc($sock))) * 16;
if ($len > 0)
{
$metadata = str_replace("\0", '', fread($sock, $len));
break;
}
else
{
$intervals++;
if ($intervals > 100) break;
}
}
$metarr = explode(';', $metadata);
foreach ($metarr as $meta)
{
$t = explode('=', $meta);
if (isset($t[0]) && trim($t[0]) != '')
{
$name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0])));
array_shift($t);
$value = trim(implode('=', $t));
if (substr($value, 0, 1) == '"' || substr($value, 0, 1) == "'")
$value = substr($value, 1);
if (substr($value, -1) == '"' || substr($value, -1) == "'")
$value = substr($value, 0, -1);
if ($value != '')
{
$tmp = &$this->metadata;
$tmp[$name] = $value;
}
}
}
$this->valid = true;
}
else
{
$this->valid = false;
}
fclose($sock);
}
else
echo 'unable to write.';
}
else
//echo 'no socket '.$errno.' - '.$errstr.'.';
;
}
You can use .xspf mountpoint extension, get XML and parse it:
<?php
$stream_url = "http://radio.hbr1.com:19800/tronic.ogg";
$xspf_url = $stream_url . ".xspf";
$xml = file_get_contents($xspf_url);
if($xml){
$data = simplexml_load_string($xml);
// Track artist
print $data->trackList->track->creator;
// Track title
print $data->trackList->track->title;
}
?>
Here is how .xspf data looks like (I use lynx to read the URL content):
$ lynx -mime_header http://radio.hbr1.com:19800/tronic.ogg.xspf
HTTP/1.0 200 OK
Content-Type: application/xspf+xml
Content-Length: 615
<?xml version="1.0" encoding="UTF-8"?>
<playlist xmlns="http://xspf.org/ns/0/" version="1">
<title/>
<creator/>
<trackList>
<track>
<location>http://radio.hbr1.com:19800/tronic.ogg</location>
<creator>Res Q</creator>
<title>Fakesleep (2012)</title>
<annotation>Stream Title: HBR1 - Tronic Lounge
Stream Description: Music on Futurenet
Content Type:application/ogg
Bitrate: Quality 0,00
Current Listeners: 28
Peak Listeners: 45
Stream Genre: Tech House, Progressive House, Electro, Minimal</annotation>
<info>http://www.hbr1.com</info>
</track>
</trackList>
</playlist>
As you can see /playlist/trackList/track/title XML node is your song title, /playlist/trackList/track/creator is usually an artist.
That's because you are only trying to parse the braindead ancient metadata slipstreaming introduced by Nullsoft in Shoutcast.
Proper streams use a container (e.g. Ogg or WebM) instead of throwing raw data out.
Newer Icecast servers offer a JSON API (Version 2.4.1 and above). This is more useful than pulling in a whole stream just for the metadata.
If you are decoding the stream anyway, then you should look into proper libraries for parsing streams, libogg, libopus, libvorbis come to mind.
I use a script from here to generate my sitemaps.
I can call it with the browser with http://www.example.com/sitemap.php?update=pages and its working fine.
I need to call it as shell script so that I can automate it with the windows task scheduler. But the script needs to be changed to get the variables ?update=pages. But I don't manage to change it correctly.
Could anybody help me so that I can execute the script from command line with
...\php C:\path\to\script\sitemap.php update=pages. It would also be fine for me to hardcode the variables into the script since I wont change them anyway.
define("BASE_URL", "http://www.example.com/");
define ('BASE_URI', $_SERVER['DOCUMENT_ROOT'] . '/');
class Sitemap {
private $compress;
private $page = 'index';
private $index = 1;
private $count = 1;
private $urls = array();
public function __construct ($compress=true) {
ini_set('memory_limit', '75M'); // 50M required per tests
$this->compress = ($compress) ? '.gz' : '';
}
public function page ($name) {
$this->save();
$this->page = $name;
$this->index = 1;
}
public function url ($url, $lastmod='', $changefreq='', $priority='') {
$url = htmlspecialchars(BASE_URL . 'xx' . $url);
$lastmod = (!empty($lastmod)) ? date('Y-m-d', strtotime($lastmod)) : false;
$changefreq = (!empty($changefreq) && in_array(strtolower($changefreq), array('always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'))) ? strtolower($changefreq) : false;
$priority = (!empty($priority) && is_numeric($priority) && abs($priority) <= 1) ? round(abs($priority), 1) : false;
if (!$lastmod && !$changefreq && !$priority) {
$this->urls[] = $url;
} else {
$url = array('loc'=>$url);
if ($lastmod !== false) $url['lastmod'] = $lastmod;
if ($changefreq !== false) $url['changefreq'] = $changefreq;
if ($priority !== false) $url['priority'] = ($priority < 1) ? $priority : '1.0';
$this->urls[] = $url;
}
if ($this->count == 50000) {
$this->save();
} else {
$this->count++;
}
}
public function close() {
$this->save();
}
private function save () {
if (empty($this->urls)) return;
$file = "sitemaps/xx-sitemap-{$this->page}-{$this->index}.xml{$this->compress}";
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
foreach ($this->urls as $url) {
$xml .= ' <url>' . "\n";
if (is_array($url)) {
foreach ($url as $key => $value) $xml .= " <{$key}>{$value}</{$key}>\n";
} else {
$xml .= " <loc>{$url}</loc>\n";
}
$xml .= ' </url>' . "\n";
}
$xml .= '</urlset>' . "\n";
$this->urls = array();
if (!empty($this->compress)) $xml = gzencode($xml, 9);
$fp = fopen(BASE_URI . $file, 'wb');
fwrite($fp, $xml);
fclose($fp);
$this->index++;
$this->count = 1;
$num = $this->index; // should have already been incremented
while (file_exists(BASE_URI . "xxb-sitemap-{$this->page}-{$num}.xml{$this->compress}")) {
unlink(BASE_URI . "xxc-sitemap-{$this->page}-{$num}.xml{$this->compress}");
$num++;
}
$this->index($file);
}
private function index ($file) {
$sitemaps = array();
$index = "sitemaps/xx-sitemap-index.xml{$this->compress}";
if (file_exists(BASE_URI . $index)) {
$xml = (!empty($this->compress)) ? gzfile(BASE_URI . $index) : file(BASE_URI . $index);
$tags = $this->xml_tag(implode('', $xml), array('sitemap'));
foreach ($tags as $xml) {
$loc = str_replace(BASE_URL, '', $this->xml_tag($xml, 'loc'));
$lastmod = $this->xml_tag($xml, 'lastmod');
$lastmod = ($lastmod) ? date('Y-m-d', strtotime($lastmod)) : date('Y-m-d');
if (file_exists(BASE_URI . $loc)) $sitemaps[$loc] = $lastmod;
}
}
$sitemaps[$file] = date('Y-m-d');
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$xml .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
foreach ($sitemaps as $loc => $lastmod) {
$xml .= ' <sitemap>' . "\n";
$xml .= ' <loc>' . BASE_URL . $loc . '</loc>' . "\n";
$xml .= ' <lastmod>' . $lastmod . '</lastmod>' . "\n";
$xml .= ' </sitemap>' . "\n";
}
$xml .= '</sitemapindex>' . "\n";
if (!empty($this->compress)) $xml = gzencode($xml, 9);
$fp = fopen(BASE_URI . $index, 'wb');
fwrite($fp, $xml);
fclose($fp);
}
private function xml_tag ($xml, $tag, &$end='') {
if (is_array($tag)) {
$tags = array();
while ($value = $this->xml_tag($xml, $tag[0], $end)) {
$tags[] = $value;
$xml = substr($xml, $end);
}
return $tags;
}
$pos = strpos($xml, "<{$tag}>");
if ($pos === false) return false;
$start = strpos($xml, '>', $pos) + 1;
$length = strpos($xml, "</{$tag}>", $start) - $start;
$end = strpos($xml, '>', $start + $length) + 1;
return ($end !== false) ? substr($xml, $start, $length) : false;
}
public function __destruct () {
$this->save();
}
}
// start part 2
$sitemap = new Sitemap;
if (get('pages')) {
$sitemap->page('pages');
$result = mysql_query("SELECT uri FROM app_uri");
while (list($url, $created) = mysql_fetch_row($result)) {
$sitemap->url($url, $created, 'monthly');
}
}
$sitemap->close();
unset ($sitemap);
function get ($name) {
return (isset($_GET['update']) && strpos($_GET['update'], $name) !== false) ? true : false;
}
?>
I could install wget (it's available for windows as well) and then call the url via localhost in the task scheduler script:
wget.exe "http://localhost/path/to/script.php?pages=test"
This way you wouldn't have to rewrite the php script.
Otherwise, if the script is meant for shell usage only, then pass variables via command line:
php yourscript.php variable1 variable2 ...
In the php script you can than access those variables using the $argv variable:
$variable1 = $argv[1];
$variable2 = $argv[2];
have a look on:
How to pass GET variables to php file with Shell?
which already answered the same question :).
I want to create a sitemap for a page with more than 30.000.000 pages. The page is daily updating, removing and adding new pages.
I found this php script which I would like to run with a cron job.
Sitemap php script
I have all URIs in the table "myuri" in the column "uri" entries are written e.g. "/this-is-a-page.html". What parameters do I need to add to the script to get it running on my table?
<?php
/*
* author: Kyle Gadd
* documentation: http://www.php-ease.com/classes/sitemap.html
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class Sitemap {
private $compress;
private $page = 'index';
private $index = 1;
private $count = 1;
private $urls = array();
public function __construct ($compress=true) {
ini_set('memory_limit', '75M'); // 50M required per tests
$this->compress = ($compress) ? '.gz' : '';
}
public function page ($name) {
$this->save();
$this->page = $name;
$this->index = 1;
}
public function url ($url, $lastmod='', $changefreq='', $priority='') {
$url = htmlspecialchars(BASE_URL . $url);
$lastmod = (!empty($lastmod)) ? date('Y-m-d', strtotime($lastmod)) : false;
$changefreq = (!empty($changefreq) && in_array(strtolower($changefreq), array('always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'))) ? strtolower($changefreq) : false;
$priority = (!empty($priority) && is_numeric($priority) && abs($priority) <= 1) ? round(abs($priority), 1) : false;
if (!$lastmod && !$changefreq && !$priority) {
$this->urls[] = $url;
} else {
$url = array('loc'=>$url);
if ($lastmod !== false) $url['lastmod'] = $lastmod;
if ($changefreq !== false) $url['changefreq'] = $changefreq;
if ($priority !== false) $url['priority'] = ($priority < 1) ? $priority : '1.0';
$this->urls[] = $url;
}
if ($this->count == 50000) {
$this->save();
} else {
$this->count++;
}
}
public function close() {
$this->save();
$this->ping_search_engines();
}
private function save () {
if (empty($this->urls)) return;
$file = "sitemap-{$this->page}-{$this->index}.xml{$this->compress}";
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
foreach ($this->urls as $url) {
$xml .= ' <url>' . "\n";
if (is_array($url)) {
foreach ($url as $key => $value) $xml .= " <{$key}>{$value}</{$key}>\n";
} else {
$xml .= " <loc>{$url}</loc>\n";
}
$xml .= ' </url>' . "\n";
}
$xml .= '</urlset>' . "\n";
$this->urls = array();
if (!empty($this->compress)) $xml = gzencode($xml, 9);
$fp = fopen(BASE_URI . $file, 'wb');
fwrite($fp, $xml);
fclose($fp);
$this->index++;
$this->count = 1;
$num = $this->index; // should have already been incremented
while (file_exists(BASE_URI . "sitemap-{$this->page}-{$num}.xml{$this->compress}")) {
unlink(BASE_URI . "sitemap-{$this->page}-{$num}.xml{$this->compress}");
$num++;
}
$this->index($file);
}
private function index ($file) {
$sitemaps = array();
$index = "sitemap-index.xml{$this->compress}";
if (file_exists(BASE_URI . $index)) {
$xml = (!empty($this->compress)) ? gzfile(BASE_URI . $index) : file(BASE_URI . $index);
$tags = $this->xml_tag(implode('', $xml), array('sitemap'));
foreach ($tags as $xml) {
$loc = str_replace(BASE_URL, '', $this->xml_tag($xml, 'loc'));
$lastmod = $this->xml_tag($xml, 'lastmod');
$lastmod = ($lastmod) ? date('Y-m-d', strtotime($lastmod)) : date('Y-m-d');
if (file_exists(BASE_URI . $loc)) $sitemaps[$loc] = $lastmod;
}
}
$sitemaps[$file] = date('Y-m-d');
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$xml .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
foreach ($sitemaps as $loc => $lastmod) {
$xml .= ' <sitemap>' . "\n";
$xml .= ' <loc>' . BASE_URL . $loc . '</loc>' . "\n";
$xml .= ' <lastmod>' . $lastmod . '</lastmod>' . "\n";
$xml .= ' </sitemap>' . "\n";
}
$xml .= '</sitemapindex>' . "\n";
if (!empty($this->compress)) $xml = gzencode($xml, 9);
$fp = fopen(BASE_URI . $index, 'wb');
fwrite($fp, $xml);
fclose($fp);
}
private function xml_tag ($xml, $tag, &$end='') {
if (is_array($tag)) {
$tags = array();
while ($value = $this->xml_tag($xml, $tag[0], $end)) {
$tags[] = $value;
$xml = substr($xml, $end);
}
return $tags;
}
$pos = strpos($xml, "<{$tag}>");
if ($pos === false) return false;
$start = strpos($xml, '>', $pos) + 1;
$length = strpos($xml, "</{$tag}>", $start) - $start;
$end = strpos($xml, '>', $start + $length) + 1;
return ($end !== false) ? substr($xml, $start, $length) : false;
}
public function ping_search_engines () {
$sitemap = BASE_URL . 'sitemap-index.xml' . $this->compress;
$engines = array();
$engines['www.google.com'] = '/webmasters/tools/ping?sitemap=' . urlencode($sitemap);
$engines['www.bing.com'] = '/webmaster/ping.aspx?siteMap=' . urlencode($sitemap);
$engines['submissions.ask.com'] = '/ping?sitemap=' . urlencode($sitemap);
foreach ($engines as $host => $path) {
if ($fp = fsockopen($host, 80)) {
$send = "HEAD $path HTTP/1.1\r\n";
$send .= "HOST: $host\r\n";
$send .= "CONNECTION: Close\r\n\r\n";
fwrite($fp, $send);
$http_response = fgets($fp, 128);
fclose($fp);
list($response, $code) = explode (' ', $http_response);
if ($code != 200) trigger_error ("{$host} ping was unsuccessful.<br />Code: {$code}<br />Response: {$response}");
}
}
}
public function __destruct () {
$this->save();
}
}
?>
There is already an example of usage on the page:
<?php
require_once ('php/classes/Sitemap.php');
$sitemap = new Sitemap;
if (get('pages')) {
$sitemap->page('pages');
$result = db_query ("SELECT url, created FROM pages"); // 20 pages
while (list($url, $created) = $result->fetch_row()) {
$sitemap->url($url, $created, 'yearly');
}
}
if (get('posts')) {
$sitemap->page('posts');
$result = db_query ("SELECT url, updated FROM posts"); // 70,000 posts
while (list($url, $updated) = $result->fetch_row()) {
$sitemap->url($url, $updated, 'monthly');
}
}
$sitemap->close();
unset ($sitemap);
function get ($name) {
return (isset($_GET['update']) && strpos($_GET['update'], $name) !== false) ? true : false;
}
?>
I would change this part....
if (get('pages')) {
$sitemap->page('pages');
$result = db_query ("SELECT uri FROM myuri");
while (list($url) = mysql_fetch_row($result)) {
$sitemap->url($url,'', 'yearly');
}
}
Not sure if that $updated is needed? Looks like the function just defaults it to an empty string anyways...... But maybe you could at a timestamp column to your table to pull the last updated date as well, and feed it into the function where I put ''.
Also....remove this part...
if (get('posts')) {
$sitemap->page('posts');
$result = db_query ("SELECT url, updated FROM posts"); // 70,000 posts
while (list($url, $updated) = $result->fetch_row()) {
$sitemap->url($url, $updated, 'monthly');
}
}
I found a script which can extract the artist & title name from an Icecast or Shoutcast stream.
I want the script to update automatically when a song changed, at the moment its working only when i execute it. I'm new to PHP so any help will be appreciated.
Thanks!
define('CRLF', "\r\n");
class streaminfo{
public $valid = false;
public $useragent = 'Winamp 2.81';
protected $headers = array();
protected $metadata = array();
public function __construct($location){
$errno = $errstr = '';
$t = parse_url($location);
$sock = fsockopen($t['host'], $t['port'], $errno, $errstr, 5);
$path = isset($t['path'])?$t['path']:'/';
if ($sock){
$request = 'GET '.$path.' HTTP/1.0' . CRLF .
'Host: ' . $t['host'] . CRLF .
'Connection: Close' . CRLF .
'User-Agent: ' . $this->useragent . CRLF .
'Accept: */*' . CRLF .
'icy-metadata: 1'.CRLF.
'icy-prebuffer: 65536'.CRLF.
(isset($t['user'])?'Authorization: Basic '.base64_encode($t['user'].':'.$t['pass']).CRLF:'').
'X-TipOfTheDay: Winamp "Classic" rulez all of them.' . CRLF . CRLF;
if (fwrite($sock, $request)){
$theaders = $line = '';
while (!feof($sock)){
$line = fgets($sock, 4096);
if('' == trim($line)){
break;
}
$theaders .= $line;
}
$theaders = explode(CRLF, $theaders);
foreach ($theaders as $header){
$t = explode(':', $header);
if (isset($t[0]) && trim($t[0]) != ''){
$name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0])));
array_shift($t);
$value = trim(implode(':', $t));
if ($value != ''){
if (is_numeric($value)){
$this->headers[$name] = (int)$value;
}else{
$this->headers[$name] = $value;
}
}
}
}
if (!isset($this->headers['icymetaint'])){
$data = ''; $metainterval = 512;
while(!feof($sock)){
$data .= fgetc($sock);
if (strlen($data) >= $metainterval) break;
}
$this->print_data($data);
$matches = array();
preg_match_all('/([\x00-\xff]{2})\x0\x0([a-z]+)=/i', $data, $matches, PREG_OFFSET_CAPTURE);
preg_match_all('/([a-z]+)=([a-z0-9\(\)\[\]., ]+)/i', $data, $matches, PREG_SPLIT_NO_EMPTY);
echo '<pre>';var_dump($matches);echo '</pre>';
$title = $artist = '';
foreach ($matches[0] as $nr => $values){
$offset = $values[1];
$length = ord($values[0]{0}) +
(ord($values[0]{1}) * 256)+
(ord($values[0]{2}) * 256*256)+
(ord($values[0]{3}) * 256*256*256);
$info = substr($data, $offset + 4, $length);
$seperator = strpos($info, '=');
$this->metadata[substr($info, 0, $seperator)] = substr($info, $seperator + 1);
if (substr($info, 0, $seperator) == 'title') $title = substr($info, $seperator + 1);
if (substr($info, 0, $seperator) == 'artist') $artist = substr($info, $seperator + 1);
}
$this->metadata['streamtitle'] = $artist . ' - ' . $title;
}else{
$metainterval = $this->headers['icymetaint'];
$intervals = 0;
$metadata = '';
while(1){
$data = '';
while(!feof($sock)){
$data .= fgetc($sock);
if (strlen($data) >= $metainterval) break;
}
//$this->print_data($data);
$len = join(unpack('c', fgetc($sock))) * 16;
if ($len > 0){
$metadata = str_replace("\0", '', fread($sock, $len));
break;
}else{
$intervals++;
if ($intervals > 100) break;
}
}
$metarr = explode(';', $metadata);
foreach ($metarr as $meta){
$t = explode('=', $meta);
if (isset($t[0]) && trim($t[0]) != ''){
$name = preg_replace('/[^a-z][^a-z0-9]*/i','', strtolower(trim($t[0])));
array_shift($t);
$value = trim(implode('=', $t));
if (substr($value, 0, 1) == '"' || substr($value, 0, 1) == "'"){
$value = substr($value, 1);
}
if (substr($value, -1) == '"' || substr($value, -1) == "'"){
$value = substr($value, 0, -1);
}
if ($value != ''){
$this->metadata[$name] = $value;
}
}
}
}
fclose($sock);
$this->valid = true;
}else echo 'unable to write.';
}else echo 'no socket '.$errno.' - '.$errstr.'.';
}
public function print_data($data){
$data = str_split($data);
$c = 0;
$string = '';
echo "<pre>\n000000 ";
foreach ($data as $char){
$string .= addcslashes($char, "\n\r\0\t");
$hex = dechex(join(unpack('C', $char)));
if ($c % 4 == 0) echo ' ';
if ($c % (4*4) == 0 && $c != 0){
foreach (str_split($string) as $s){
//echo " $string\n";
if (ord($s) < 32 || ord($s) > 126){
echo '\\'.ord($s);
}else{
echo $s;
}
}
echo "\n";
$string = '';
echo str_pad($c, 6, '0', STR_PAD_LEFT).' ';
}
if (strlen($hex) < 1) $hex = '00';
if (strlen($hex) < 2) $hex = '0'.$hex;
echo $hex.' ';
$c++;
}
echo " $string\n</pre>";
}
public function __get($name){
if (isset($this->metadata[$name])){
return $this->metadata[$name];
}
if (isset($this->headers[$name])){
return $this->headers[$name];
}
return null;
}
}
$t = new streaminfo('http://64.236.34.196:80/stream/1014'); // get metadata
echo Meta Interval: $t->icymetaint;
echo Current Track: $t->streamtitle;
You will need to constantly query the stream at a set interval to find when the song changes.
This can be best done by scheduling a cron job.
If on Windows, you should use the Windows Task Scheduler
If you want to run the PHP script to keep your meta data up to date (I'm assuming you're making a website and using html audio tags here) you can use the ontimeupdate event with an ajax function. If you're not you probably should look up your audio playback documentation for something similar.
<audio src="http://ip:port/;" ontimeupdate="loadXMLDoc()">
You can find a great example here http://www.w3schools.com/php/php_ajax_php.asp
You want to use the PHP echo function all the relevant information at once using one php variable at the very end of your script.
<?php ....
$phpVar=$streamtitle;
$phpVar2=$streamsong;
$result="I want my string to look like this: <br> {$phpVar} {$phpVar2}";
echo $result;
?>
and then use the function called by the .onreadystatechange to modify the particular elements you want on your website by using the .resonseText (this will contain the same content as your PHP script's echo).
After SCOURING the web for 4 hours, this is the only Shoutcast metadata script I've found that works! Thankyou.
To run this constantly, why not use a setInterval combined with jQuery's AJAX call?
<script>
$(function() {
setInterval(getTrackName,16000);
});
function getTrackName() {
$.ajax({
url: "track_name.php"
})
.done(function( data ) {
$( "#results" ).text( data );
});
}
</script>
Also your last couple 'echo' lines were breaking the script for me. Just put quotes around the Meta Interval, etc....