Ярлыки

.htaccess (4) тестирование (8) шаблоны проектирования (3) css (5) Debian (6) docker (2) Doctrine2 (6) Git (6) html (4) java (6) javascript (13) jquery (11) LFS (3) linux (23) mac os (4) mod_rewrite (2) MSSQL (4) MySQL (18) ORM Doctrine (17) patterns (3) PDO (3) perl (7) PHP (64) PHPUnit (8) Python (15) SEO (2) Silex (1) SimpleXML (1) SQL (14) ssh (4) Ubuntu (24) Yii1 (1) Zend Framework (19) ZendFramework2 (8)

воскресенье, 31 января 2010 г.

Пейджинг с ORM Doctrine (практика).

В предыдущих публикациях была теория, ну а теперь немного практики, вот фрагмент кода:

$current_page = intval($args[2]);
$results_per_page = 5;

$pager_layout = new PagerLayoutWithArrows (
new Doctrine_Pager (
Doctrine_Query :: create ()
->from ( "Message m" )
->orderBy ( "id DESC" ),
$current_page ,
$results_per_page
),
new Doctrine_Pager_Range_Sliding (
array ( "chunk" => 5 )),
"тут ваш адрес/{%page_number}"
);

$pager_layout ->setTemplate ('<a href="{%url}" class="pager">{%page}</a>');
$pager_layout ->setSelectedTemplate ('<b class="pager">{%page}</b>');
$pager = $pager_layout ->getPager ();
$messages = $pager->execute()->getData();

$this->registry->template->messages = $messages;
$this->registry->template->pager = $pager_layout ->display('',true);
$this->registry->template->show('тут название шаблона');


Ну а вот наш класс-наследник PagerLayoutWithArrows, для удобства мы переопределим класс Doctrine_Pager_Layout, чтобы у нас выводилась более продвинутая навигация:

class PagerLayoutWithArrows extends Doctrine_Pager_Layout {
public function display($options = array(), $return = false) {
$pager = $this->getPager();
$str = '';

// First page
$this->addMaskReplacement('page', '«', true);
$options['page_number'] = $pager->getFirstPage();
$str .= $this->processPage($options);

// Previous page
$this->addMaskReplacement('page', '‹', true);
$options['page_number'] = $pager->getPreviousPage();
$str .= $this->processPage($options);

// Pages listing
$this->removeMaskReplacement('page');
$str .= parent::display($options, true);

// Next page
$this->addMaskReplacement('page', '›', true);
$options['page_number'] = $pager->getNextPage();
$str .= $this->processPage($options);

// Last page
$this->addMaskReplacement('page', '»', true);
$options['page_number'] = $pager->getLastPage();
$str .= $this->processPage($options);

// Possible wish to return value instead of print it on screen
if ($return) {
return $str;
}

echo $str;
}
}

Из руководства Doctrine 1.1 вольный перевод. Пейджинг (продолжение).

Виды стилей виджетов постраничного вывода.

Есть несколько случаев, когда простых пейджеров недостаточно. Одним из примеров является ситуация, когда вы хотите создать перечисления ссылок на страницы. Для более мощного контроля над поведением пейджера, есть небольшая часть пакета пейджинга, которая позволяет вам создавать диапазоны.

В настоящее время ORM Doctrine реализует два типа (или стиля) диапазонов: скольжение (слайдинг, реализовано в Doctrine_Pager_Range_Sliding) и прыжки (jumping, реализовано в Doctrine_Pager_Range_Jumping).

Слайдинг.

Раздвижной (слайдер) стиль диапазона страниц, на странице плавно переходит с текущей страницы. Текущая страница всегда в центре, за исключением первой и последней страницы диапазона. Проверьте, как она работает на примере длинной 5 пунктов:


Listing 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Page 1: o-------|
Page 2: |-o-----|
Page 3: |---o---|
Page 4: |---o---|
Page 5: |---o---|
Page 6: |---o---|
Page 7: |---o---|
Page 8: |---o---|


Джампинг.
Диапазон ссылок на странице всегда ссылается на фиксированный набор фреймов 1-5, 6-10, 11-15 и так далее.

Listing 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Page 1: o-------|
Page 2: |-o-----|
Page 3: |---o---|
Page 4: |-----o-|
Page 5: |-------o
Page 6: o---------|
Page 7: |-o-------|
Page 8: |---o-----|


Теперь, когда мы знаем, каким образом ведут себя различные стили работы пейджера, настало время научиться использовать их:


$pagerRange = new Doctrine_Pager_Range_Sliding(
array(
'chunk' => 5 // Chunk length
),
$pager // Doctrine_Pager object we learned how to create in previous topic
);


или другой вариант:


$pagerRange = $pager->getRange(
'Sliding',
array(
'chunk' => 5
)
);


В чем состоит преимущество использования данного объекта, а не Doctrine_Pager? Только в одном - он позволяет получить диапазоны вокруг текущей страницы.

Посмотрите на пример:


// Retrieves the range around the current page
// In our example, we are using sliding style and we are at page 1
$pages = $pager_range->rangeAroundPage();

// Outputs: [1][2][3][4][5]
echo '['. implode('][', $pages) .']';


Если вы строите свой Doctrine_Pager внутри диапазона объектов, API предоставляет вам достаточно возможностей, чтобы получить информацию, связанную с подклассом Doctrine_Pager_Range, например:


// Return the Pager associated to this Pager_Range
$pager_range->getPager();

// Defines a new Doctrine_Pager (automatically call _initialize protected method)
$pager_range->setPager($pager);

// Return the options assigned to the current Pager_Range
$pager_range->getOptions();

// Returns the custom Doctrine_Pager_Range implementation offset option
$pager_range->getOption($option);

// Check if a given page is in the range
$pager_range->isInRange($page);

// Return the range around the current page (obtained from Doctrine_Pager
// associated to the $pager_range instance)
$pager_range->rangeAroundPage();

Из руководства Doctrine 1.1 вольный перевод. Пейджинг (начало).

Пейджинг.

Введение.

В реальных web-приложениях, отображать содержимое таблиц базы данных является одной из самых распространенных задач. Кроме того, представьте себе, что это содержание результатов поиска, содержащее тысячи позиций. К сожалению, возможно это будет огромный список, значительное потребление памяти и может вызвать дискомфорт у пользователя. Именно в таких ситуация нам и необходим постраничный вывод (pagination, pager, пейджер).

В ORM Doctrine присутствует очень гибкая реализация пейджинга, которая позволяет Вам не только организовать постраничных вывод данных, но и контролировать расположение виджета пейджера на web-странице. В этой главе мы узнаем, как создавать объекты пейджера, стили управления постраничным выводом и в конце, обзор объекта шаблона постраничного вывода (pager layout object) — мощного средства ORM Doctrine для отображения ссылок на страницы с вашими данными.

Работа с пейджером.

Постраничные запросы так же просты как и обычные. За постраничный вывод отвечает объект Doctrine_Pager. Это иллюстрирует пример кода ниже:


// Defining initial variables
$currentPage = 1; // текущая страница
$resultsPerPage = 50; // количество записей, выводимых на страницу

// Creating pager object
$pager = new Doctrine_Pager(
Doctrine_Query::create()
->from( 'User u' )
->leftJoin( 'u.Group g' )
->orderby( 'u.username ASC' ),
$currentPage, // Current page of request
$resultsPerPage // (Optional) Number of results per page. Default is 25
);


Здесь у вас есть источник в виде объекта класса Doctrine_Query. Единственным отличием является то, что теперь у вас есть 2 новых аргумента. Ваш старый объект запроса к базе данных плюс эти 2 аргумента передаются в коструктор объекта Doctrine_Pager. На данном этапе, Doctrine_Pager определяет основные данные, необходимые для контроля нумерации данных для вывода. Если вы хотите знать, что на самом деле делает пейджер, для начала надо проверить был ли он выполнен:

$pager->getExecuted();


Если вы пытаетесь получить доступ к любым из методов, предусмотренных по Doctrine_Pager сейчас, вы получите исключение Doctrine_Pager_Exception сообщающее вам, что пейджер еще не был выполнен. После выполнении Doctrine_Pager предлагаем Вам эффективные методы для получения информации. Использование API, перечислены в конце этой темы.

Метод выполнения Doctrine_Pager очень похож на подобный метод класса Doctrine_Query. Он также позволяет передавать аргументы, как вы обычно это делаете. Ниже приведен синтаксис PHP, включая синтаксис передачи дополнительных параметров:


$items = $pager->execute([$args = array() [, $fetchType = null]]);

foreach ($items as $item) {
// ...
}


Существуют некоторые особые случаи, когда запрос возващающий записи отличается от запроса подсчета. Чтобы разрешить эту ситуацию, Doctrine_Pager имеет некоторые методы, которые позволяют рассчитать, а затем выполнить. Первое, что вам нужно сделать, это определить запрос-счетчик:


$pager->setCountQuery($query [, $params = null]);

// ...

$rs = $pager->execute();


Первый параметр в setCountQuery может быть действительным объектом Doctrine_Query или строкой DQL. Вторым аргументом можно указать дополнительные параметры, которые могут быть отправлены в запросе-счетчике. Если вы не определите параметры сразу, то сможете определить в любой момент , вызвав setCountQueryParams:

$pager->setCountQueryParams([$params = array() [, $append = false]]);


Этот метод принимает 2 параметра. Первый параметр будут направлены в запрос-счетчик, а второй параметр, если $params должен быть добавлен к списку, или если он должен переопределить список параметров, количество запросов. Поведение по умолчанию - переопределить список. И последнее, что касается запроса-счетчика, если вы не определяете никаких параметров для него, то будут отправлены параметры, которые определяются в вызове $pager->execute ().

Запрос-счетчик всегда доступен. Если вы не определили его и вызывали $pager-> getCountQuery (), будет возвращен "fetcher" query.

Если вам нужно получить доступ к другой функции, которые Doctrine_Pager предоставляет, вы можете получить к ним доступ через API:


// Returns the check if Pager was already executed
// проверка выполнения пейджера
$pager->getExecuted();

// Return the total number of itens found on query search
// возвращает количество записей найденных по запросу
$pager->getNumResults();

// Return the first page (always 1)
// возвращает первую страницу
$pager->getFirstPage();

// Return the total number of pages
// возвращает общее количество страниц
$pager->getLastPage();

// Return the current page
// возвращает текущую страницу
$pager->getPage();





// Defines a new current page (need to call execute again to adjust offsets and values)
// переопределяет текущую страницу
$pager->setPage($page);

// Return the next page
// возвращает следующую страницу
$pager->getNextPage();

// Return the previous page
// возвращает предыдущую страницу
$pager->getPreviousPage();

// Return the first indice of current page
$pager->getFirstIndice();

// Return the last indice of current page
$pager->getLastIndice();

// Return true if it's necessary to paginate or false if not
// возвращает true если надо делать постраничный вывод
$pager->haveToPaginate();

// Return the maximum number of records per page
// максимальное количество записей на страницу
$pager->getMaxPerPage();

// Defined a new maximum number of records per page (need to call execute again to adjust offset and values)
// определяет новое максимальное количество записей на страницу
$pager->setMaxPerPage($maxPerPage);

// Returns the number of itens in current page
// количество записей на текущей странице
$pager->getResultsInPage();

// Returns the Doctrine_Query object that is used to make the count results to pager
// возвращает объект Doctrine_Query, который используется для запроса подсчета результатов для пейджера
$pager->getCountQuery();

// Defines the counter query to be used by pager
// определяет запрос-счетчик
$pager->setCountQuery($query, $params = null);

// Returns the params to be used by counter Doctrine_Query (return $defaultParams if no param is defined)
$pager->getCountQueryParams($defaultParams = array());

// Defines the params to be used by counter Doctrine_Query
$pager->setCountQueryParams($params = array(), $append = false);

// Return the Doctrine_Query object
$pager->getQuery();

// Return an associated Doctrine_Pager_Range_* instance
$pager->getRange($rangeStyle, $options = array());

Список около 250 url сайтов-каталогов с PageRank выше 2 медицинской тематики.

Список около 250 сайтов-каталогов с PageRank выше 2, медицинской тематики.

скачать --- catalogs_medicine_pr2+

Закрываем системное окно(диалог) в Xedant Human Emulator

Бывает что я работаю с замечательным инструментом для seo - Xedant Human Emulator. Для тех кто не в курсе это движок браузера Internet Explorer, снабженный графической оболочкой, управляемый скриптами на php и имеющий встроенный редактор для их написания. Призвано это все без лишней головной боли автоматизировать действия пользователя в интернете.
В общем о программе лучше будет почитать на ее оф.сайте.

Я же буду иногда выкидывать сюда маленкие хитрости при написании скриптов. Так скажем не совсем документированные возможности.

На пример, как закрыть системный диалог, вызванный ie (не javascript).

Функция которая возвращает номер окна по его заголоку:
function get_window_num($text) 
{
    // объект библиотеки XHE для работы с окнами
    global $window;
    $list = explode('<br>', $window->get_all_texts('true', 'true'));
    $i = 0;
    foreach($list as $w) {
        if($w == $text) break;
        $i++;
    }
    return $i;
}

Пример:
$n = get_window_num("загловок окна");
// жмем кнопку по тексту в ней например "Да"
$window->press_button_by_text_in_window_by_number($n, 'Да', 'false', 'true', 'false');

Таким образом мы ответили в диалоге Windows "Да". Вот так можно автоматизровать массу рутинных действий в интернете,
связанных с поисковой оптимизацией, автоматическую регистрацию на сайтах и в каталогах, автоматическую публикацию сообщений и сбор информации.

Продолжение про русский язык, кодировку utf8 и ORM Doctrine

На самом деле вероятно многие тоже сталкивались с проблемой русских заглавной буквы И и буквы ш, в кодировке utf8 c ними возникают проблемы. Речь идет про ORM Doctrine. В общем все решается так:
$manager = Doctrine_Manager::getInstance();
$manager->openConnection(DSN, 'doctrine');
$manager->setCharset("utf8");
$manager->setCollate("utf8_general_ci");
$manager->setAttribute('model_loading', 'conservative')
$conn = $manager->getConnection("doctrine");
// PDO
$dbh = $conn->getDbh();

$sql = "SET character_set_results = 'utf8', character_set_client = 'utf8',
character_set_connection = 'utf8', character_set_database = 'utf8',
character_set_server = 'utf8'";

// аналогично
// $sql = "SET NAMES 'utf8'";

$dbh->query($sql);