Карта сайта (phpFOX: SiteMap)

Начинаем внедрять генератор карты. Для начала создаем папку: file/sitemap/, папка остается пустой, после того, как закончим, там появятся xml файлы (карты). Возможно для создания папки, придется изменить права доступа на папку file, если так, то после создания, необходимо вернуть права, как было.

Теперь переходим к редактированию файла: include/setting/common.sett.php, открываем его и в самый низ добавляем строки:
# SiteMap
$_CONF['core.dir_sitemap'] = $_CONF['core.dir_file'] . 'sitemap' . PHPFOX_DS;
$_CONF['core.url_sitemap'] = $_CONF['core.url_file'] . 'sitemap/'; 

Дальше я написал следующий код (файл: sitemap.class.php):
<?php
class Common_Service_Sitemap_Sitemap extends Phpfox_Service
{
    private $map = array(
        'blog',
        'forum_thread',
        'music_song',
        'photo',
        'user'
    );

    public function __construct()
    {
        $url = array();
        foreach ($this->map as $item)
        {
            $url['loc'][]        = Phpfox::getParam('core.url_sitemap') . $item .'.xml';
            $url['lastmod'][]    = PHPFOX_TIME;
            $url['changefreq'][] = 'daily';
            $url['priority'][]   = '0.5';
        }

        $file = Phpfox::getParam('core.dir_sitemap') . 'sitemap.xml';
        $this->creation($url, $file);
        $this->receipt();        
    }

    private function receipt()
    {
        foreach ($this->map as $item)
        {
            $rows = Phpfox::getLib('database')
                ->select('*')
                ->from(Phpfox::getT($item))
                ->execute('getSlaveRows');

            $this->area($item, $rows);
        }
    }

    private function area($item, $rows)
    {
        $url = array();
        foreach ($rows as $row)
        {
            if ($item != 'user')
            {
                $title = Phpfox::getService('common')->unicyrillic($row['title']);
                $title = Phpfox::getService('common')->cleansymbols($title);
                $title = mb_strtolower($title);
            }

            if ($item == 'blog')
            {
                $url['loc'][]        = Phpfox::getParam('core.path') . 'blog/' . $row['blog_id'] . '/' . $title . '/';
                $url['lastmod'][]    = !empty($row['time_update']) ? $row['time_update'] : $row['time_stamp'];
                $url['changefreq'][] = 'weekly';
                $url['priority'][]   = '0.5';
            }            
            else if ($item == 'forum_thread')
            {
                $url['loc'][]        = Phpfox::getParam('core.path') . 'forum/thread/' . $row['thread_id'] . '/' . $title . '/';
                $url['lastmod'][]    = !empty($row['time_update']) ? $row['time_update'] : $row['time_stamp'];
                $url['changefreq'][] = 'daily';
                $url['priority'][]   = '0.5';
            }
            else if ($item == 'music_song')
            {
                $url['loc'][]        = Phpfox::getParam('core.path') . 'music/' . $row['song_id'] . '/' . $title . '/';
                $url['lastmod'][]    = $row['time_stamp'];
                $url['changefreq'][] = 'monthly';
                $url['priority'][]   = '0.5';
            }
            else if ($item == 'photo')
            {
                $url['loc'][]        = Phpfox::getParam('core.path') . 'photo/' . $row['photo_id'] . '/' . $title . '/';
                $url['lastmod'][]    = $row['time_stamp'];
                $url['changefreq'][] = 'monthly';
                $url['priority'][]   = '0.5';
            }
            else if ($item == 'user')
            {
                if ($row['user_name'])
                {
                    $url['loc'][]        = Phpfox::getParam('core.path') . $row['user_name'] . '/';
                    $url['lastmod'][]    = !empty($row['last_activity']) ? $row['last_activity'] : $row['joined'];
                    $url['changefreq'][] = 'monthly';
                    $url['priority'][]   = '0.5';
                }                
            }
        }

        $file = Phpfox::getParam('core.dir_sitemap') . $item . '.xml';
        $this->creation($url, $file);
    }

    private function creation($url, $file)
    {
        $xml  = '<?xml version="1.0" encoding="UTF-8"?>'                       . "\r\n";
        $xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\r\n";
        for ($i = 0; $i < count($url['loc']); $i++)
        {
            $xml .= '    <url>'                                                                   . "\r\n";
            $xml .= '        <loc>'        . $url['loc'][$i]                    . '</loc> '       . "\r\n";
            $xml .= '        <lastmod>'    . date('Y-m-d', $url['lastmod'][$i]) . '</lastmod>'    . "\r\n";
            $xml .= '        <changefreq>' . $url['changefreq'][$i]             . '</changefreq>' . "\r\n";
            $xml .= '        <priority>'   . $url['priority'][$i]               . '</priority>'   . "\r\n";
            $xml .= '    </url>'                                                                  . "\r\n";
        }
        $xml .= '</urlset>';

        $fopen = fopen($file, 'w');
        $write = fwrite($fopen, $xml);
        fclose($fopen);
    }        
}

Из кода видно, что карты генерируются только для пяти разделов: blog, forum_thread, music_song, photo и user. Мне пока больше не надо (возможно в будущем понадобиться еще). Вы можете добавить больше разделов, если это требуется.

В данном классе используются функции unicyrillic и cleansymbols - это не "родные" функции движка. Вот тут: Phpfox::getService('common') используется мною созданный модуль common, будьте внимательны, если у вас нет модуля с таким же названием, его необходимо создать, либо изменить название при обращении к файлам. В модуле common (файл: module/common/include/service/common.class.php), у меня две функции unicyrillic и cleansymbols:
    # Перевод юникода в кириллицу
    public function unicyrillic($string)
    {
        $cyrillic = array('а', 'А', 'б', 'Б', 'в', 'В', 'г', 'Г', 'ґ', 'Ґ', 'д', 'Д', 'е', 'Е', 'є', 'Є', 'ё', 'Ё', 'ж', 'Ж', 'з', 'З', 'і', 'І', 'ї', 'Ї', 'и', 'И', 'й', 'Й', 'к', 'К', 'л', 'Л', 'м', 'М', 'н', 'Н', 'о', 'О', 'п', 'П', 'р', 'Р', 'с', 'С', 'т', 'Т', 'у', 'У', 'ф', 'Ф', 'х', 'Х', 'ц', 'Ц', 'ч', 'Ч', 'ш', 'Ш', 'щ', 'Щ', 'ъ', 'Ъ', 'ы', 'Ы', 'ь', 'Ь', 'э', 'Э', 'ю', 'Ю', 'я', 'Я');
        $unicode  = array('&#1072;', '&#1040;', '&#1073;', '&#1041;', '&#1074;', '&#1042;', '&#1075;', '&#1043;', '&#1169;', '&#1168;', '&#1076;', '&#1044;', '&#1077;', '&#1045;', '&#1108;', '&#1028;', '&#1105;', '&#1025;', '&#1078;', '&#1046;', '&#1079;', '&#1047;', '&#1110;', '&#1030;', '&#1111;', '&#1031;', '&#1080;', '&#1048;', '&#1081;', '&#1049;', '&#1082;', '&#1050;', '&#1083;', '&#1051;', '&#1084;', '&#1052;', '&#1085;', '&#1053;', '&#1086;', '&#1054;', '&#1087;', '&#1055;', '&#1088;', '&#1056;', '&#1089;', '&#1057;', '&#1090;', '&#1058;', '&#1091;', '&#1059;', '&#1092;', '&#1060;', '&#1093;', '&#1061;', '&#1094;', '&#1062;', '&#1095;', '&#1063;', '&#1096;', '&#1064;', '&#1097;', '&#1065;', '&#1098;', '&#1066;', '&#1099;', '&#1067;', '&#1100;', '&#1068;', '&#1101;', '&#1069;', '&#1102;', '&#1070;', '&#1103;', '&#1071;');
        $symbol   = array('№');
        $ucode    = array('&#8470;');

        $string = str_replace($unicode, $cyrillic, $string);
        $string = str_replace($ucode,   $symbol,   $string);

        return $string;        
    }
    # Перевод юникода в кириллицу END

    # Очистка от символов
    public function cleansymbols($string)
    {
        $string = str_replace(array('.', ',', ':', '!', '?', '(', ')', '[', ']'), '', $string);
        $string = str_replace(array(' ', '|'), '-', $string);
        $string = preg_replace('|-{2,}|', '-', $string);

        return $string;
    }
    # Очистка от символов END       

К слову: эти две функции можно просто вставить в файл sitemap.class.php, тогда не придется делать дополнительный файл, однако надо помнить, что имя модуля common, при необходимости изменить во всех местах. Файл: sitemap.class.php, помещаем в папку: module/common/include/service/sitemap/.

И заключительный этап - это добавление строки в таблицу БД cron:
- module_id common (или свое название модуля)
- product_id phpfox
- next_run 0
- last_run 0
- type_id 3
- every 1
- is_active 1
- php_code Phpfox::getService('common.sitemap'); (или свое название модуля)
Должно получиться так:
Карта сайта (phpFOX: SiteMap)
После чего чистим кэш. Готово.
На данный момент генератор находится в виде отдельной библиотеки и выглядит так:
<?php
class phpfox_seo_sitemap
{
	private $map = [
		'blog',
		'forum_thread',
		'photo',
		'poll',
		'video'
	];

	public function __construct()
	{
		foreach ($this->map as $item)
		{
			$rows = phpfox::getLib('database')
				->select('*')
				->from(phpfox::getT($item))
				->execute('getSlaveRows');

			$this->area($item, $rows);
		}
	}

	private function area($item, $rows)
	{
		$path = phpfox::getParam('core.path');
		$url = [];
		foreach ($rows as $row)
		{
			if ($item == 'blog')
			{
				$url['loc'][]        = $path . 'blog/' . $row['blog_id'] . '/';
				$url['lastmod'][]    = !empty($row['time_update']) ? $row['time_update'] : $row['time_stamp'];
				$url['changefreq'][] = 'weekly';
				$url['priority'][]   = '0.5';
			}
			else if ($item == 'forum_thread')
			{
				$url['loc'][]        = $path . 'forum/thread/' . $row['thread_id'] . '/';
				$url['lastmod'][]    = $row['time_update'];
				$url['changefreq'][] = 'daily';
				$url['priority'][]   = '0.5';
			}
			else if ($item == 'photo')
			{
				$url['loc'][]        = $path . 'photo/' . $row['photo_id'] . '/';
				$url['lastmod'][]    = $row['time_stamp'];
				$url['changefreq'][] = 'yearly';
				$url['priority'][]   = '0.5';
			}
			else if ($item == 'poll')
			{
				$url['loc'][]        = $path . 'poll/' . $row['poll_id'] . '/';
				$url['lastmod'][]    = $row['time_stamp'];
				$url['changefreq'][] = 'yearly';
				$url['priority'][]   = '0.5';
			}
			else if ($item == 'video')
			{
				$url['loc'][]        = $path . 'video/' . $row['video_id'] . '/';
				$url['lastmod'][]    = $row['time_stamp'];
				$url['changefreq'][] = 'yearly';
				$url['priority'][]   = '0.5';
			}
		}

		$file = phpfox::getParam('core.dir_sitemap') . $item . '.xml';
		$this->creation($url, $file);
	}

	private function creation($url, $file)
	{
		$count = count($url['loc']);

		$xml  = '<?xml version="1.0" encoding="UTF-8"?>'                       . "\r\n";
		$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\r\n";
		for ($i = 0; $i < $count; $i++)
		{
			$xml .= "\t"   . '<url>'                                                               . "\r\n";
			$xml .= "\t\t" . '<loc>'        . $url['loc'][$i]                    . '</loc>'        . "\r\n";
			$xml .= "\t\t" . '<lastmod>'    . date('Y-m-d', $url['lastmod'][$i]) . '</lastmod>'    . "\r\n";
			$xml .= "\t\t" . '<changefreq>' . $url['changefreq'][$i]             . '</changefreq>' . "\r\n";
			$xml .= "\t\t" . '<priority>'   . $url['priority'][$i]               . '</priority>'   . "\r\n";
			$xml .= "\t"   . '</url>'                                                              . "\r\n";
		}
		$xml .= '</urlset>';

		$fopen = fopen($file, 'w');
		$write = fwrite($fopen, $xml);
		fclose($fopen);
	}
}