+10.10
Рейтинг
16.92
Сила

Gordon Shumway

  • avatar ALF
  • 2
Прикручиваем поиск noov-a к 0.3 — поехали:

\classes\actions\ActionSearch.class.php

<?
/*-------------------------------------------------------
*
*   LiveStreet Engine Social Networking
*   Copyright © 2008 Mzhelskiy Maxim
*
*--------------------------------------------------------
*
*   Official site: www.livestreet.ru
*   Contact e-mail: rus.engine@gmail.com
*
*   GNU General Public License, version 2:
*   http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
---------------------------------------------------------
*/

/**
 * Обрабатывает поиск по тегам
 *
 */
class ActionSearch extends Action {	
	/**
	 * Инициализация
	 *
	 */
	public function Init() {		
		/**
		 * Определяем какие блоки выводить
		 */
	}
	
	protected function RegisterEvent() {						
	}
		
	
	/**********************************************************************************
	 ************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
	 **********************************************************************************
	 */
	
	/**
	 * Отображение топиков
	 *
	 */
	protected function EventNotFound() {
		/**
		 * Получаем тег из УРЛа
		 */
		$sTag=urldecode($this->sCurrentEvent);
		//$sTag = str_replace ('?searchfor=', '', $sTag);

			$sTag = $_POST['q'];
			
		if (strlen($sTag)<=6) 
		{
		    $sTag = '!!Слишком!!короткий!!поисковый!!запрос!!';
		} 			

		//$sTag0 = htmlspecialchars($sTag, ENT_QUOTES);
		//$sTag = $sTag0;
		$bad = array ("`","~","@","#","$","%","^","&","*","-","=","+","{","}",">","<",",","?","/","|");
		$repl = array ("","","","","","","","","","","","","","","","","","","","");
		$sTag = str_replace ($bad, $repl, $sTag);
		/**
		 * Передан ли номер страницы
		 */
		if (preg_match("/^page(\d+)$/i",$this->getParam(0),$aMatch)) {			
			$iPage=$aMatch[1];
		} else {
			$iPage=1;
		}		
		/**
		 * Получаем список топиков
		 */
		$iCount=0;			
		//$aResult=$this->Topic_GetTopicsByTag($sTag,$iCount,$iPage,BLOG_TOPIC_PER_PAGE);		
		$aResult=$this->Topic_GetTopicsBySearch($sTag,$iCount,$iPage,BLOG_TOPIC_PER_PAGE);
		$aTopics=$aResult['collection'];	
		/**
		 * Формируем постраничность
		 */		
		$aPaging=$this->Viewer_MakePaging($aResult['count'],$iPage,BLOG_TOPIC_PER_PAGE,4,DIR_WEB_ROOT.'/search/topics/'.htmlspecialchars($sTag));
		/**
		 * Загружаем переменные в шаблон
		 */				
		$this->Viewer_Assign('aTopics',$aTopics);
		$this->Viewer_Assign('aPaging',$aPaging);
		$this->Viewer_Assign('sTag',$sTag);
		$this->Viewer_AddHtmlTitle('Поиск');
		$this->Viewer_AddHtmlTitle($sTag);
		/**
		 * Устанавливаем шаблон вывода
		 */
		$this->SetTemplateAction('index');		
	}	
}
?>


Берём функцию из этого сообщения:
livestreet.ru/blog/909.html#comment12233
и вставляем её в Topic.mapper.class.php

Создаём папку:
\templates\skin\new\actions\ActionSearch
В этой папке создаём файлик index.tpl к следующего содержания:

{include file='header.tpl' showWhiteBack=true}

<h1>Поиск</h1>
<form action="{$DIR_WEB_ROOT}/{$ROUTE_PAGE_SEARCH}/topics/" method="POST">
	<p>
		<input type="text" value="" name="q" class="w300">
		<input type="submit" value="Найти">
	</p>
</form>

{include file='topic_list.tpl'}

{include file='footer.tpl'}


Никакого java скрипта специально добавлять не нужно.
Вроде ничего не забыл, если что поправьте меня.
Извиняюсь за портянку.
  • avatar ALF
  • 1


Присоединюсь.
  • avatar ALF
  • 0
Приветствую Вас Уважаемый Sergey12! Из того что Вы перечислили ничего специально прописывать не нужно. WampServer — это самая что ни наесть обычная солянка из апача, мускула и т. д.
  • avatar ALF
  • 1
Примите мою безмерную благодарность Уважаемый ort! Я долго мучился с этим сжатием, но не знал что это можно организовать через сам nginx — просто документация на него такая запутанная.
  • avatar ALF
  • 1
Вот чистилка для 0.3:
(только умоляю — поосторожнее с ней)

<code><?PHP

$bConfig=include("./config/config.php");
$cConfig=include("./config/config.table.php");

   $dConfig=include("./config/config.db.php");
   $sDSN=$dConfig['type'].'://'.$dConfig['user'].':'.$dConfig['pass'].'@'.$dConfig['host'].':'.$dConfig['port'].'/'.$dConfig['dbname'];		

  //Цепляем класс
   require_once "./classes/lib/external/DbSimple/Generic.php";
  //Создаём объект
   $oDbSimple=DbSimple_Generic::connect($sDSN);

function cleaning_filesystem($dirname)  {

global $oDbSimple;

    if  (is_dir($dirname))
        $dir_handle  =  opendir($dirname);
    if  (!$dir_handle)
        return  false;
     
		//Перебираем
		while(($file  =  readdir($dir_handle))!==false)  {
            if  ($file  !=  "."  &&  $file  !=  ".." && ereg("avatar", $file)!=TRUE)  {
                if  (!is_dir($dirname."/".$file)) {
                   
                    //Проверяем 
                    $sql = $oDbSimple->select("SELECT topic_id FROM ".DB_TABLE_TOPIC_CONTENT." WHERE topic_text_source LIKE '%$file%'");
                    $a=count($sql);
                       $sql = $oDbSimple->select("SELECT page_id FROM ".DB_TABLE_PAGE." WHERE page_text LIKE '%$file%'");
                       $a=$a+count($sql);
                          $sql = $oDbSimple->select("SELECT comment_id FROM ".DB_TABLE_TOPIC_COMMENT." WHERE comment_text LIKE '%$file%'");
                          $a=$a+count($sql);
							 $sql = $oDbSimple->select("SELECT user_id FROM ".DB_TABLE_USER." WHERE user_profile_foto LIKE '%$file%'");
                             $a=$a+count($sql);
                   
                   //Удаляем
                    if ($a==0) {
                        if (unlink($dirname."/".$file))
                       //Если файл удалился, то выводим на экран сообщение об успехе
                        { echo "<font color='green'>DELETED</font>".' '.$dirname."/".$file."
\n"; }
                            else
                       //Если файл не удалился, то выводим на экран сообщение об ошибке
                        { echo "<font color='red'>DELETED</font>".' '.$dirname."/".$file."
\n"; }
                    }	
					
				}					
					
                else 
			   //Рекурсия
                cleaning_filesystem($dirname.'/'.$file);                       
            }
        }
       //Закрываем
        closedir($dir_handle);
       //Удаляем
        @rmdir($dirname);
       //Возвращаем
        return  true;
} 

$dirname=".".DIR_UPLOADS_IMAGES;
cleaning_filesystem($dirname);

?></code>


Заранее извиняюсь за «портянку».
  • avatar ALF
  • 1
Тут видео добавляется двумя способами, в зависимости от настройки в конфиге. Вариантов два:

1. Если включён редактор TinyMCE, да возникнут проблемы. Нельзя от пользователей требовать править код видео.

2. Если TinyMCE выключен, то движок использует другой редактор, в нём пользователю нужно просто обрамить ссылку на видео тегом video, а уже парсер сам разберётся каким кодом его нужно подменить.

В файле:

\classes\modules\sys_text\Text.class.php

строки со 107 по 113 отвечают за подмену ссылки кодом.

  • avatar ALF
  • 1
Благодарю, уважаемый Vilz! Вариант с transparent гарантированно работает в Opera и FF (в explorer-е не проверил).
  • avatar ALF
  • 0
На самом деле на эту тему можно очень долго рассуждать. «Проблема замедления выборки из директории с большим количеством файлов» это довольно неоднозначная, спорная и по большей части теоретическая. Файловые системы разные, все они имеют свои преимущества и свои недостатки. К тому же стоит добавить, что всё течёт, всё меняется. Но перестраховаться да, не помешает. К тому же на любом этапе жизни портала всё можно, при желании, переиграть.
  • avatar ALF
  • 1
Здравствуйте Уважаемый noonv!

Проблема с постраничным выводом результатов поиска была в следующем:
В файле Topic.mapper.class.php в функции GetTopicsBySearch необходимо было посчитать вначале общее количество строк в таблице удовлетворяющих поисковому запросу, а уже во втором запросе вытаскивать данные относящиеся к конкретной странице результатов. Осталось только оптимизировать первый запрос, что бы он выдавал только количество строк. Я бы и рад это сделать, но в SQL я увы не силён — для меня это тёмный лес.

<code>//
	// поиск текста по топикам
	//
	public function GetTopicsBySearch($sTag,&$iCount,$iCurrPage,$iPerPage) 
	{
		$iCurrentUserId=-1;
		if (is_object($this->oUserCurrent)) {
			$iCurrentUserId=$this->oUserCurrent->getId();
		}
		$sql = "	SELECT
						t.*,
                        tc.*,
                        u.user_login as user_login,
                        b.blog_title as blog_title,
						b.blog_type as blog_type,
						b.blog_url as blog_url,
                        IF(tv.topic_id IS NULL,0,1) as user_is_vote,
						tv.vote_delta as user_vote_delta,
						IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote 
					FROM (				
							SELECT DISTINCT 
								topic_id										
							FROM 
								".DB_TABLE_TOPIC_CONTENT."								
							WHERE 
							LOWER(topic_text_source) LIKE LOWER('%{$sTag}%')
							UNION
								
								SELECT DISTINCT 
									topic_id											
								FROM ".DB_TABLE_TOPIC." 
								WHERE 
								LOWER(topic_title) LIKE LOWER('%{$sTag}%')
								
								ORDER BY topic_id DESC				
						 ) as tt

						 JOIN ".DB_TABLE_TOPIC." AS t ON tt.topic_id=t.topic_id
						 JOIN ".DB_TABLE_USER." AS u ON t.user_id=u.user_id
						 JOIN ".DB_TABLE_BLOG." AS b ON t.blog_id=b.blog_id	
						 LEFT JOIN (
								SELECT
									topic_id,
									vote_delta												
								FROM ".DB_TABLE_TOPIC_VOTE." 
								WHERE user_voter_id = ?d
								) AS tv ON tt.topic_id=tv.topic_id
						 LEFT JOIN (
								SELECT
									topic_id																			
								FROM ".DB_TABLE_TOPIC_QUESTION_VOTE." 
								WHERE user_voter_id = ?d
								) AS tqv ON tt.topic_id=tqv.topic_id
                         LEFT JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON tt.topic_id=tc.topic_id
				;	
					";

		$iCount=0;
		if ($aRows=$this->oDb->select($sql,$sTag,($iCurrPage-1)*$iPerPage, $iPerPage,$iCurrentUserId,$iCurrentUserId)) {
			foreach ($aRows as &$value) {
				$iCount++;
			}
		}

	    $Start=($iCurrPage*$iPerPage)-$iPerPage;

		$sql = "	SELECT
						t.*,
                        tc.*,
                        u.user_login as user_login,
                        b.blog_title as blog_title,
						b.blog_type as blog_type,
						b.blog_url as blog_url,
                        IF(tv.topic_id IS NULL,0,1) as user_is_vote,
						tv.vote_delta as user_vote_delta,
						IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote 
					FROM (				
							SELECT DISTINCT 
								topic_id										
							FROM 
								".DB_TABLE_TOPIC_CONTENT."								
							WHERE 
							LOWER(topic_text_source) LIKE LOWER('%{$sTag}%')
							UNION
								
								SELECT DISTINCT 
									topic_id											
								FROM ".DB_TABLE_TOPIC." 
								WHERE 
								LOWER(topic_title) LIKE LOWER('%{$sTag}%')
								
								ORDER BY topic_id DESC				
						        LIMIT ".$Start.", ".$iPerPage."
						 ) as tt

						 JOIN ".DB_TABLE_TOPIC." AS t ON tt.topic_id=t.topic_id
						 JOIN ".DB_TABLE_USER." AS u ON t.user_id=u.user_id
						 JOIN ".DB_TABLE_BLOG." AS b ON t.blog_id=b.blog_id	
						 LEFT JOIN (
								SELECT
									topic_id,
									vote_delta												
								FROM ".DB_TABLE_TOPIC_VOTE." 
								WHERE user_voter_id = ?d
								) AS tv ON tt.topic_id=tv.topic_id
						 LEFT JOIN (
								SELECT
									topic_id																			
								FROM ".DB_TABLE_TOPIC_QUESTION_VOTE." 
								WHERE user_voter_id = ?d
								) AS tqv ON tt.topic_id=tqv.topic_id
                         LEFT JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON tt.topic_id=tc.topic_id
				;	
					";

		$aTopics=array();
		if ($aRows=$this->oDb->select($sql,$sTag,($iCurrPage-1)*$iPerPage, $iPerPage,$iCurrentUserId,$iCurrentUserId)) {
			foreach ($aRows as $aTopic) {
				$aTopics[]=new TopicEntity_Topic($aTopic);
			}
		}
		return $aTopics;
	}</code>


С уважением ALF.
  • avatar ALF
  • 1
Мы уже плавно перешли к обсуждению версии 0.3
В версии 0.2 да, там всё именно так как Вы описали, а вот в 0.3 такая ситуация:

livestreet.ru/uploads/images/2/2/8/3/1306/f21ab38509.jpg

В ранних ревизиях 0.3 фотки пользователей разбрасывались произвольно по директории images в рандомных подпапках, а как в свежих ревизиях обстоит дело с этим я затруднюсь ответить.
  • avatar ALF
  • 0
Можно и в 0.3 прибраться.

Тут возможны два варианта — один простой, второй тоже не сложный.

1. Простой:

Отучаем саму LiveStreet «мусорить» — убираем в самой системы раскладывание по кучам папок (там насколько я помню просто рандомная функция натыкана), и делаем имена сохраняемых файлов подлиннее (навряд ли пользователь зальёт столько изображений, что имена файлов будут временами совпадать). В этом случае система просто будет складировать файлы в одну директорию закреплённую за пользователем. Так же необходимо ещё добавить в этот скрипт проверку поля фотографий пользователей в таблице с пользователями.

(Этот вариант подойдёт для тех, кто ставит систему с нуля)

2. Посложнее, так как в этом случае нужно «чесать репу», а это всегда «лениво».

Добавить в этот скрипт ещё парочку циклов, и тем самым научить его ковыряться в подпапках. Соответственно так же нужно добавить проверку фотографий.

(Этот вариант подойдёт для тех, у кого сайт уже с контентом)

***

В случае с VDS и полноценным дедиком проблемы с файловым мусором не стоит — там места водоём, а вот для небольших сообществ у которых система крутится на обычном виртуальном хосте эта проблема теоретически может возникнуть.