* @license PHP License
* @package WB
* @subpackage content
*/
/**
* Load base class
*/
WBClass::load('WBContent');
/**
* Content component: SearchEngineOptimizer
*
* Display robots.txt and sitemap
*
* @deprecated in favour of subclasses of WBContent_SEO
* @version 0.4.1
* @package WB
* @subpackage content
*/
class WBContent_SearchEngineOptimizer extends WBContent
{
/**
* my parameter list
*
* - 'process' select what to display (sitemap, robots.txt)
* - 'page' whether to add pages to sitemap (0,1)
* - 'blog' add blog articles to sitemap (blog/%day/%title)
* - 'blogcategory' list of blog categories (optional)
* - 'gallery' add gallery pages to sitemap (gallery/%obscureid/%title)
* - 'vfs' add media files page to sitemap (vfs/%obscureid/%name)
* - 'vfsmimemajor' limit to file types - don't care for mimetype if empty
*
* @var array
*/
protected $config = array(
'process' => 'sitemap',
'page' => 1,
'blog' => '', // blog/%day/%title
'blogcategory' => array(),
'gallery' => '', // gallery/%obscureid/%title
'vfs' => '', // vfs/%obscureid/%name
'vfsmimemajor' => array('video', 'image')
);
/**
* url template for google sitemap
*
* @var string
*/
protected $url = "http://[[SERVER]][[SERVICE_HTML]]%s%1.2f\n";
/**
* list of found or not to add (to sitemap) pages
* @var array
*/
protected $pages = array(
'/robot' => true,
'/robots.txt' => true,
'/sitemap' => true,
'/sitemap.xml' => true
);
/**
* current menu level
* @var int
*/
protected $level = 0;
/**
* vfs gallery
* @var WBVFS_Gallery
*/
protected $gallery;
/**
* Table access
* @var WBDatasource_Table
*/
private $table;
/**
* config loader
* @var WBConfig_Loader
*/
private $configLoader;
/**
* run
*
* run component
*
* @return array parameter list
*/
public function run()
{
switch (strtolower($this->config['process'])) {
case 'robots.txt';
case 'robots';
$this->displayRobots();
break;
case 'sitemap':
default:
$this->displaySitemap();
break;
}
return $this->config;
}
/**
* create standard robots.txt
*
* @link http://www.robotstxt.org/
* @uses display()
*/
protected function displayRobots()
{
$cnt = <<display($cnt, 'text/plain');
}
/**
* create standard google sitemap
*
* @link http://www.sitemaps.org/
* @uses display()
*/
protected function displaySitemap()
{
// reset locale settings to make sure decimal point works properly
setlocale(LC_ALL, null);
$cnt = <<
EOT;
$this->addPage2Sitemap($cnt);
$this->addBlog2Sitemap($cnt);
$this->addGallery2Sitemap($cnt);
$this->addVFS2Sitemap($cnt);
$cnt .= "\n";
$this->display($cnt, 'text/xml');
}
/**
* add blog article pages
*
* In case there are special blog article pages, list recent 100 article URLs
*
* See config option 'blog. If this parameter is empty, nothing will be added to
* the sitemap. Otherwise path to each article is used. The placeholder %id and
* %title are replaced with article's id and title.
*
* @param string $cnt
*/
protected function addBlog2Sitemap(&$cnt)
{
if (empty($this->config['blog'])) {
return;
}
// basic blog path
$path = $this->config['blog'];
$path = str_replace(array('%id', '%title'), '', $path);
$path = trim($path, '/');
$level = count(explode('/', $path));
// priority of blog article pages
$prio = 1 - ($level / 10);
$path = $this->config['blog'];
// fetch recent 100 acticles
if (!$this->table) {
$this->table = WBClass::create('WBDatasource_Table');
}
$opt = array(
'limit' => 500,
'column' => array('title', 'created')
);
$clause = array();
if (!empty($this->config['blogcategory'])) {
if (!is_array($this->config['blogcategory'])) {
$this->config['blogcategory'] = array($this->config['blogcategory']);
}
$clause[] = array(
'field' => $this->table->getIdentifier('blogcategory'),
'relation' => 'in',
'value' => $this->config['blogcategory']
);
}
$list = $this->table->get('blog', null, null, $clause, $opt);
$search = array(
'%id',
'%day',
'%title'
);
foreach ($list as $l) {
$replace = array(
$l['id'],
date('Y-m-d', strtotime($l['created'])),
urlencode($l['title'])
);
$p = str_replace($search, $replace, $path);
$cnt .= sprintf($this->url, $p, $prio);
}
WBDatasource_Table::flushCache();
}
/**
* add list of galleries to sitemap
*
* In case there automatically created special pages for gallery listings,
* load list of user galleries and add them to sitemap
*
* @param string $cnt
*/
protected function addGallery2Sitemap(&$cnt)
{
if (empty($this->config['gallery'])) {
return;
}
// basic blog path
$path = $this->config['gallery'];
$path = str_replace(array('%obscureid', '%title'), '', $path);
$path = trim($path, '/');
$level = count(explode('/', $path));
// priority of gallery list page
$prio = 1 - ($level / 10);
$path = $this->config['gallery'];
$options = array();
$this->gallery = WBClass::create('WBVFS_Gallery', $options);
$search = array(
'%obscureid',
'%title'
);
$list = $this->gallery->getList();
foreach ($list as $l) {
$replace = array(
$l['obscureid'],
urlencode($l['title'])
);
$p = str_replace($search, $replace, $path);
$cnt .= sprintf($this->url, $p, $prio);
}
WBDatasource_Table::flushCache();
}
/**
* add media files
*
* @param string $cnt
*/
protected function addVFS2Sitemap(&$cnt)
{
if (empty($this->config['vfs'])) {
return;
}
if (!$this->table) {
$this->table = WBClass::create('WBDatasource_Table');
}
$opt = array(
'limit' => 500,
'order' => array(
'field' => 'created',
'asc' => 0
)
);
$clause = array();
// description is required
$clause[] = array(
'field' => 'description',
'relation' => 'not',
'value' => ''
);
// just a view mime-types
if (!empty($this->config['vfsmimemajor'])) {
if (!is_array($this->config['mimemajor'])) {
$this->config['mimemajor'] = array($this->config['mimemajor']);
}
$clause[] = array(
'field' => 'mimemajor',
'relation' => 'in',
'value' => $this->config['vfsmimemajor']
);
}
$list = $this->table->getIds('vfsfile', null, $clause, $opt);
$search = array(
'%obscureid',
'%name'
);
$file = WBClass::create('WBVFS_File');
/** @var $file WBVFS_File */
foreach ($list as $l) {
$file = $file->loadById($l);
if (!$file->isOK()) {
continue;
}
/**
* @todo check for file references
*/
$major = $file->getMime(WBVFS_File::MIME_MAJOR);
// add vfs file view page
$replace = array(
$file->getObscureId(),
urlencode($file->getName())
);
$m = array('');
$m[] = sprintf(' http://[[SERVER]][[SERVICE_HTML]]%s', str_replace($search, $replace, $this->config['vfs']));
$m[] = sprintf(' <%s:%1$s>', $major);
$m[] = sprintf(' <%s:title>%1$s:title>', $major, $file->getName());
switch ($major) {
case 'image':
$m[] = sprintf(' <%s:loc>http://[[SERVER]][[SERVICE_FILE]]%s%1$s:loc>', $major, $file->getUri());
$m[] = sprintf(' <%s:caption>%1$s:caption>', $major, $file->getDescription());
break;
case 'video':
$created = strtotime($file->getCreated());
$m[] = sprintf(' <%s:publication_date>%s%1$s:publication_date>', $major, strftime('%Y-%m-%dT%H:%M:%S+00:00', $created));
$m[] = sprintf(' <%s:content_loc>http://[[SERVER]][[SERVICE_FILE]]%s%1$s:content_loc>', $major, $file->getUri());
$m[] = sprintf(' <%s:player_loc allow_embed="yes" autoplay="autostart=true">http://[[SERVER]][[SERVICE_JAVASCRIPT]]WB/player.swf?file=[[SERVICE_FILE]]%s%1$s:player_loc>', $major, $file->getUri());
$m[] = sprintf(' <%s:thumbnail_loc>http://[[SERVER]][[SERVICE_FILE]]%s%1$s:thumbnail_loc>', $major, $file->getUri('image'));
$m[] = sprintf(' <%s:description>%1$s:description>', $major, $file->getDescription());
$m[] = sprintf(' <%s:duration>%d%1$s:duration>', $major, round($file->getInfo('seconds')));
$m[] = sprintf(' <%s:view_count>%d%1$s:view_count>', $major, $file->getViews());
break;
default:
continue 2;
break;
}
$m[] = sprintf(' %s:%1$s>', $major);
$m[] = '';
$m[] = '';
$cnt .= implode("\n", $m);
}
WBDatasource_Table::flushCache();
}
/**
* add all configured pages
*
* @todo implement switch for pages stored in database
* @param string $cnt
* @todo move old code to WBConfigLoader_File
*/
protected function addPage2Sitemap(&$cnt)
{
if (empty($this->config['page']) || intval($this->config['page']) < 1) {
return;
}
$loader = WBParam::get('wb/config/loader/service/site', 'File');
if ($loader != 'File') {
$this->configLoader = WBClass::create('WBConfig_Loader_' . WBParam::get('wb/config/loader/service/site', 'File'));
$this->addPages2Sitemap($cnt);
return;
}
$cnt .= sprintf($this->url, '', 1);
// add pages from page configuration folders
$etcDir = WBParam::get('wb/dir/base')
. '/'
. WBParam::get( 'wb/dir/config', 'etc' );
if (is_dir($etcDir . '/site/page')) {
$this->addPageDir2Sitemap($cnt, $etcDir . '/site/page');
}
$this->addPageDir2Sitemap($cnt, $etcDir . '-default/site/page');
}
/**
* list pages in sitemap
*
* Recursive method to load find all page configurations and add them
* to sitemap.
*
* @param string $cnt
* @param string $path
*/
private function addPages2Sitemap(&$cnt, $path = '')
{
$path = trim($path, '/');
$branch = array_pop(explode('/', $path));
if (strncmp('__', $branch, 2) == 0) {
return;
}
if (isset($this->pages[$path])) {
return;
}
$this->pages['/' . $path] = true;
$prio = 1.1 - (count(explode('/', $path)) / 10);
$cnt .= sprintf($this->url, $path, $prio);
// try to find children
if (!empty($path)) {
$path = '/' . $path;
}
$children = $this->configLoader->ls('site/page' . $path);
if (empty($children)) {
return;
}
foreach ($children as $child) {
$child = substr($child, 10);
$this->addPages2Sitemap($cnt, $child);
}
}
/**
* add pages to sitemap
*
* Recursively scans folder for page definitions. It also makes sure, that each page
* will be added just once.
*
* @uses display()
* @param string $cnt
* @param string $dir
* @param string $prefix
* @todo move to WBConfig_Loader_File
*/
protected function addPageDir2Sitemap(&$cnt, $dir, $prefix = '')
{
$iter = new DirectoryIterator($dir);
foreach ($iter as $page) {
if ($page->isDot()) {
continue;
}
if ($page->isDir()) {
++$this->level;
$this->addPageDir2Sitemap($cnt, $page->getPathname(), $prefix . $page->getFilename() . '/');
--$this->level;
continue;
}
$name = explode('.', $page->getFilename());
if (array_pop($name) != 'xml') {
continue;
}
$name = implode('.', $name);
// skip index and default pages
if (strncmp($name, '__', 2) == 0) {
continue;
}
$name = $prefix . $name;
// make sure each page will be added only once
if (isset($this->pages[$name])) {
continue;
}
$this->pages[$name] = true;
$prio = 1 - ($this->level / 10);
$cnt .= sprintf($this->url, $name, $prio);
}
}
/**
* Display
*
* CAUTION: This method does not return!
*
* @param string $content
* @param string $mime
*/
protected function display($content, $mime)
{
$res = WBClass::create('WBResponse');
/** @var $res WBResponse */
$res->add($content);
$res->addHeader('Content-Type', $mime);
$res->send($this->req);
exit(0);
}
}