+0.65
Рейтинг
1.71
Сила

Дмитрий

Разработка под ЛС. 1000 руб/час

Много разных задач по редизайну сайта www.7dach.ru
Новый дизайн в процессе — dev2.habicasa.ru

  • Есть задачи чисто CSS
  • Есть задачи jQuery, в т.ч. интеграция Aloha Editor
  • Есть задачи под PHP
  • Есть задачи по доработке модулей Nginx

Нужен человек, готовый погрузиться в проект и тратить на него 15-30 часов в неделю.

Предоплату мы не делаем. Для разработки готовы предоставить настроенный тестовый сервер. Начинаете работать, выполнять сначала мелкие задачи, их сразу оплачиваем по факту выполнения.

Все вопросы пишите в личку или skype — ddegtyarev

UPD:
1. Мы не оплачиваем стратегический консалтинг, инновационные идеи, философские размышления. Мы оплачиваем кодинг в виде коммитов в нашу репу.
2. У нас нет интересных или прикольных задач, решение которых прославит вас или обогатит новыми знаниями. Есть задачи по кодингу согласно подробному ТЗ, в виде тасков в нашей репе (github)
3. Весь оплаченный нами код становится нашей собственностью, и перестает быть вашей.
4. Наш проект требует погружения. Работать по полчаса в день не получится.
5. Если вас не мотивируют деньги, мы вряд ли будем вам интересны.
6. Если вы не можете оперативно отвечать на скайп/почту/лс в рабочее время, или хотя бы обозначить период, когда возможна такая коммуникация, мы не захотим с вами работать.

UPD2:
Я в отпуске по 2 июля, отвечать на письма в это время скорее всего не смогу.

Какую лицензию использовать для платных плагинов?

Пост вопросов


1. Какую лицензию рекомендуют использовать авторы движка?

2. Является ли плагин «derived from the Program or any part thereof»? Это вообще тонкий вопрос, ведь плагин как правило переопределяет классы движка, которые в свою очередь под лицензией GPLv2, а она в свою очередь требует что бы и плагин был GPLv2 (читаем пункт 2 лицензии)

b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.

Буду признателен на ссылки на холивары по этому поводу.

3. Как разработчикам например плагина autoopenid удалось продать 400 лицензий по 10 баксов, при этом почти во всех файлах там висит заголовок с GPLv2, т.е. бери, копируй, выкладывай в каталог за 9 баксов или за 1 бакс или бесплатно?

В сообществе LS все джентельмены? Или главный пахан следит чтобы все было «по понятиям»?

Как сделать чтобы редактор TinyMCE не открывался слишком длинным

При редактировании длинных статей в TinyMCE было очень неудобно из-за того, что панель инструментов оставалась в начале статьи, и приходилось постоянно скроллировать вверх-вниз. После получаса поисков и эскпериментов было найдено решение:

Читать дальше →

Выполнено: Плагин для массового назначения тэгов топикам

UPD: Плагин доступен в каталоге https://catalog.livestreetcms.com/addon/view/340/

  • Создать плагин habitagadmin
  • Доступен только администраторам
  • Выглядит в стиле aceadminpanel
  • Позволяет отнимать и назначать тэги топикам
  • Создает два пункта меню: Тэги и Тэггирование топиков
  • По первому пункту показывается список тэгов

    • с фильтрацией по названию
    • с возможностью удалить или переименовать некоторые тэги.

      • удаление тэга значит, что у всех топиков он стирается из поля тэгов и топики пересохраняются
      • переименование значит, что у всех топиков содержащих данный тэг он стирается, и заместо него записывается другой. Не допускать дублирования тэгов у топика!

    • с возможностью кликнуть на кол-во топиков в таблице и попасть на список топиков с этим тэгом — см вторую страницу Тэггирование топиков
  • По второму пункту открывается таблица с топиками

    • с фильтрацией по подстроке в названии
    • с фильтрацией по подстроке в списке тэгов — автоматически заполняется при переходе из списка тэгов

    • с фильтрацией по блогу: в выбиралке «все блоги», «личные блоги», и каждый коллективный отдельно
    • с фильтрацией по неделе публикации — в выбиралке показываются все недели начиная с февраля 2013
    • с сортировкой по автору или названию
    • в таблице показываются

      • первая строка: автор, название
      • вторая строка: в одной колонке все тэги через запятую
        • при клике на тэги, они превращаются в редактируемое поле
        • при нажатии Enter поле сохраняется AJAX-ом и обратно превращается в текст

      • третья строка: в одной колонке первые 250 символов текста топика мелким шрифтом
    • возможность отметить один, несколько или все топики. Повторное нажатие на чекбокс в шапке таблицы приводит к развыделению всех топиков.
    • возможность удалить и/или добавить тэг к выбранным топикам


habitagadmin mockup

UPD: плагин реализован, обращайтесь в личку

Как сделать склонение числительных функцией mysql (mysql declension function)

UPD: Мне для разового SQL запроса потребовалось получить строки с правильным склонением числительных напрямую из базы данных mysql. Погуглив я не нашел ничего подходящего. Создавать PHP скрипт мне показалось дольше, поэтому было принято решение написать функцию.

Я совсем не рекомендую теперь везде и всегда делать склонение таким образом. В шаблонизаторе LiveStreet есть встроенный механизм declension, рекомендуется пользоваться им.

Прошу воспринимать данный код как пример создания фукции в базе данных MySQL, для тех, кому это интересно. Внимание: использование функций и хранимых процедур может сделать ваш код менее переносимым, менее масштабируемым, более медленным и увеличить нагрузку на СУБД.


Читать дальше →

Выполнено: Доработка плагина LS autoopenid: вход через одноклассники, ЖЖ и mail.ru

Необходимо расширить функционал плагина autoopenid следующим образом

1. Добавить в список кнопок для логина еще 3 кнопки: Одноклассники, ЖЖ, mail.ru. Картинки кнопок надо создать или найти в инете.

2. По кнопке одноклассники должна происходить регистрация/авторизация через одноклассники, с заполнением профиля пользователя, аватарки и т.д. Весь процесс должен быть аналогичен таковому для вконтакте, включая привязку профилей.

3. ID приложения в одноклассниках должно задаваться в config.php, ну собственно там же, где и остальные параметры плагина

4. ЖЖ и mail.ru поддерживают OpenId, но юзеры этого не знают, поэтому по кнопкам ЖЖ и mail.ru, должно происходить то же, что и по ссылке «Указать OpenID», а именно появление поле ввода, однако в случае с ЖЖ и mail.ru дополнительно:

— Заголовок над полем ввода должен быть «Ваш логин в ЖЖ» или «Ваш логин в Mail.ru»

— Перед полем ввода должен быть текст http://

— За полем ввода должен быть текст .livejournal.com/ или .id.mail.ru

— Текст до и после поля ввода выводить назначить класс и выводить серым шрифтом

— Из введенного юзером логина должен формироваться урл вида exampleusername.livejournal.com/

или exampleusername.id.mail.ru и дальше передаваться на обработку по существующуй схеме авторизации через OpenID

Бюджет начнем с 3000 руб

UPD: Вход через Однокласснкии сделан, используется у нас на www.7dach.ru
При наличии интереса отпишитесь — дооформлю и выложу в каталог.

UPD: Плагин реализован. Желающие приобрести — в личку.

Как заставить CSS и JS обновляться автоматически при обновлении файлов

У нас на сервере включена полезная опция объединения всех JS и CSS файлов. Задается она в конфиге

/**
 * Параметры компрессии css-файлов
 */
$config['compress']['css']['merge'] = true;       // указывает на необходимость слияния файлов по указанным блокам.
$config['compress']['js']['merge']  = true; 


Однако при обновлении исходников JS и CSS файлов пользователи не получают обновления. Я видел есть плагин ReloadCSS однако он не занимается JS файлами, плюс тыкать кнопку мне тоже не охота совсем. В итоге я полез в код движка и нашел место, где формируется название скомпрессированных файлов

engine/modules/viewer/Viewer.class.php функция Compress
        /**
	 * Сжимает все переданные файлы в один,
	 * использует файловое кеширование
	 *
	 * @param  array  $aFiles	Список файлов
	 * @param  string $sType	Тип файла - js, css
	 * @return array
	 */
	protected function Compress($aFiles,$sType) {
		$sCacheDir  = $this->sCacheDir."/".Config::Get('view.skin');
		$sCacheName = $sCacheDir."/".md5(serialize($aFiles).'_head').".{$sType}";
		$sPathWeb    = Config::Get('path.root.web');
		/**
		 * Если кеш существует, то берем из кеша
		 */
		if(!file_exists($sCacheName)) {


Видно, что в формировании ключа участвуют только имена файлов. Я добавил туда еще и размеры, заодно проверил скорость формирования ключа. Вот такой код у меня получился:

	/**
	 * Сжимает все переданные файлы в один,
	 * использует файловое кеширование
	 *
	 * @param  array  $aFiles	Список файлов
	 * @param  string $sType	Тип файла - js, css
	 * @return array
	 */
	protected function Compress($aFiles,$sType) {
		$sPathWeb    = Config::Get('path.root.web');
		$aFileDates = array();
		$iStart = microtime(true);
		foreach ($aFiles as $sFile) {
			// если файл локальный
			if (strpos($sFile, $sPathWeb)!==false) {
				$sFile=$this->GetServerPath($sFile);
				list($sFile,)=explode('?',$sFile,2);
				$aFileDates[] = filectime($sFile);
			}
		}
		$sCacheDir  = $this->sCacheDir."/".Config::Get('view.skin');
		$sCacheName = $sCacheDir."/".md5(implode($aFiles).implode($aFileDates).'_head').".{$sType}";
		echo "Key calculation took ".(microtime(true) - $iStart)." secs\n";
		/**
		 * Если кеш существует, то берем из кеша
		 */
		if(!file_exists($sCacheName)) {


Проверка показала, что время пренебрежимо мало:

Key calculation took 0,0016648769378662 secs
Key calculation took 0,0010089874267578 secs


Убираем отладочный вывод и радумеся обновлениям JS и CSS.

Можно было бы это сделать плагином, но в плагине пришлось бы переопределить функцию Compress. Может, лучше это изменение просто включить в следующую версию LS.

[Создан] Плагин расчета авторских гонораров

Техзадание на LS плагин расчета авторских гонораров

Назначение плагина:
Упростить труд модератора по оценке вклада авторов в создание контента на сайте, и выплате гонораров.

Требования:
  • вывод списком постов и комментов
  • проставление признака и процента полезности прямо из списка
  • расчет кол-ва символов без пробелов и тэгов
  • расчет кол-ва фото в посте/комменте
  • фильтрация по дате создания (указание периода)
  • фильтрация по автору
  • фильтрация по типу: топик/комментарий
  • фильтрация по мин кол-ву символов
  • фильтрация по мин полезности
  • фильтрация по мин полезности поста (это только для комментариев, можно попросить вывести все комментарии только к “полезным” постам)
  • подсчет суммарных значений
  • настройка кол-ва выводимых символом из тела поста
  • экспорт в csv
  • интеграция в админку LS, доступ только администратору. В меню пункт называется “Расчет гонорара”

Подход к реализации

  • код оформляется как полноценный независимый плагин к LS, без вмешательства в ядро или другие плагины
  • Для работы плагина необходима установка плагина aceadminpanel
  • В качестве обучающего примера можно взять admintopic — это подсказка разработчику
  • Название плагина — habihonorar

ТЗ на плагин расчет гонорара

Серые подписи не надо реализовывать, это комментарии к макету

Комментарии к статистике:

  • Полезность измеряется в процентах.
  • Полезных расчитывается среди всех постов с полезностью > 0.
  • Взвешенно расситывается как сумма показателей по каждому посту с коэффициентом полезности.

Условия передачи кода и оплата
Весь код передается в экслюзивную собственность заказчика. Заказчик имеет возможность выставить плагин в продажу через каталог LS. При получении оплаты исполнитель лично или по электронной почте присылает расписку, подтверждающую передачу кода заказчику.

Связь через skype: ddegtyarev

UPD: Плагин создан, ожидайте появления в каталоге

Как сделать чтобы описание блога показывалось сразу

Сначала что получилось:
Шапка блога без раскрытых деталей
Шапка блога с раскрытыми деталями
Ну собственно для того, чтобы это случилось я просто в файле templates/skin/synio/actions/ActionBlog/blog.tpl строчку

<p class="blog-description">{$oBlog->getDescription()}</p>
перенес повыше из div class=«blog-content» в div class=«blog-top»

Настройки SphinxSearch 2.0.4 поставленного в Ubuntu 12.04 командой apt-get

Я ставил Sphinx на Ubuntu 12.04. Использую облачный сервер Selectel, поэтому все операции выполнялись под root.
  1. В Ubuntu SphinxSearch 2.0.4 ставится простой командой
    apt-get install sphinxsearch

  2. Правим файл /etc/default/sphinxsearch и ставим START=yes
  3. Создаем файл /etc/sphinxsearch/sphinx.conf
    Я изначально взял отсюда: Sphinx. Установка и первичная настройка, и поправил пути, а также заменил deprecated address на listen.

    Также оказалось что таблица topic_comment теперь называется comment, поправил это тоже.
    ## Конфигурационный файл Sphinx-а для индексации Живой улицы
    
    #######################
    #
    # Описываем индексы
    #
    #######################
    
    # Источник-родитель для всех остальных источников. Здесь указываются параметры доступа 
    # к базе данных сайта
    source lsParentSource
    {
    	type		= mysql
    	sql_host	= localhost
    	sql_user	= root
    	sql_pass	= 
    	sql_db		= livestreet
    	sql_port	= 3306
        	# Для ускорения работы прописываем путь до MySQL-го UNIX-сокета (чтобы 
    	# операции с БД происходили не через TCP/IP стек сервера)
        	sql_sock	= /var/run/mysqld/mysqld.sock
        
        	
    	mysql_connect_flags	= 32 # 32- включение сжатие при обмене данными с БД
        
    	# Включам нужную кодировку соединения и выключаем кеш запросов
    	sql_query_pre			= SET NAMES utf8
        	sql_query_pre			= SET SESSION query_cache_type=OFF    
    }
    
    # Источник топиков
    source topicsSource : lsParentSource
    {
    	# запрос на получения данных топиков
    	sql_query		= \
    		SELECT t_fast.topic_id, t_fast.topic_title, UNIX_TIMESTAMP(t_fast.topic_date_add) as topic_date_add, \
    		tc.topic_text, t_fast.topic_publish \
    		FROM prefix_topic as t_fast, prefix_topic_content AS tc \
    		WHERE t_fast.topic_id=tc.topic_id AND t_fast.topic_id>=$start AND t_fast.topic_id<=$end
    
    	# запрос для дробления получения топиков на неколько итераций
    	sql_query_range		= SELECT MIN(topic_id),MAX(topic_id) FROM prefix_topic
    	
    	# сколько получать объектов за итерацию
    	sql_range_step		= 1000
    
    	
    	# Указываем булевый атрибут критерия "топик опубликован". Для возможности указания этого критерия при поиске
    	sql_attr_bool		= topic_publish
    
    	# Атрибут даты добавления, типа "время"
    	sql_attr_timestamp	= topic_date_add
    
    	# мульти-аттрибут "теги топика"
    	sql_attr_multi	= uint tag from query; SELECT topic_id, topic_tag_id FROM prefix_topic_tag
    
    	sql_ranged_throttle	= 0
    }
    
    # Источник комментариев
    source commentsSource : lsParentSource
    {
    	sql_query		= \
    			SELECT comment_id, comment_text, UNIX_TIMESTAMP(comment_date) as comment_date, comment_delete \
    			FROM prefix_comment \
    			WHERE comment_id>=$start AND comment_id<=$end
    
    	sql_query_range		= SELECT MIN(comment_id),MAX(comment_id) FROM prefix_comment
    	sql_range_step		= 5000
    
    	sql_attr_bool		= comment_delete
    	sql_attr_timestamp	= comment_date
    }
    
    #######################
    #
    # Описываем индексы
    #
    #######################
    
    index topicsIndex
    {
    	# Источник, который будет хранить данный индекса
    	source			= topicsSource
    	path			= /var/lib/sphinxsearch/data/lstopics
    
    	# Тип хранения аттрибутов
    	docinfo			= extern
    
    	mlock			= 0
    
    	# Используемые морфологические движки
    	morphology		= stem_enru, soundex, metaphone
    
    	# Кодировака данных из источника	
    	charset_type		= utf-8
    
    
    	# Из данных источника HTML-код нужно вырезать
    	html_strip				= 1
    }
    
    # Индекс комментариев
    index commentsIndex
    {
    	source			= commentsSource
    	path			= /var/lib/sphinxsearch/data/lscomments
    
    	docinfo			= extern
    
    	mlock			= 0
    
    	morphology		= stem_enru, soundex, metaphone
    
    	charset_type		= utf-8
    }
    
    #######################
    #
    # Настройки индексатора
    #
    #######################
    
    
    indexer
    {
    	# Лимит памяти, который может использавать демон-индексатор
    	mem_limit			= 32M
    }
    
    #######################
    #
    # Настройка демона-поисковика
    #
    #######################
    
    searchd
    {
            # Адрес, на котором будет прослушиваться порт
            listen                  = 127.0.0.1:3312
    
    	# Лог-файл демона
    	log					= /var/log/sphinxsearch/searchd.log
    
    	# Лог поисковых запросов. Если закомментировать,то логировать поисковые строки не будет
    	query_log			= /var/log/sphinxsearch/query.log
    
    	# Время в секундах, которое ждет демон при обмене данными с клиентом. По исчерпании происходит разрыв коннекта
    	read_timeout		= 5
    
    	# Максимальное количество одновременно-обрабатываемых запросов. 0 означает дофига, а точнее без ограничения
    	max_children		= 30
    
    	# Файл, в который сохраняется PID-процесса при запуске
    	pid_file			= /var/run/sphinxsearch/searchd.pid
    }

  4. Правим настройки для соединения с базой
    source lsParentSource
    {
            type            = mysql
            sql_host        = localhost
            sql_user        = root
            sql_pass        =
            sql_db          = livestreet
            sql_port        = 3306
    

  5. Правим префикс таблиц. В моем случае я заменил все вхождения prefix_ на пустоту. (6 замен)
  6. Индексацию будем делать под пользователем sphinxsearch, для этого надо ему выставить /bin/sh в виде шелла
    chsh -s /bin/sh sphinxsearch

  7. Запускаем индексацию из-под юзера sphinxsearch
    su sphinxsearch -c 'indexer --all'

    Индерксатор не должен выдавать ошибок, и должны появиться файлы индексов в папке /var/lib/sphinxsearch/data/
  8. Запускаем искалку
    service sphinxsearch start

  9. Проверяем, что поиск работает. У меня заработал.
  10. Ставим переиндексацию на крон. Для этого редактируем кронтаб для пользователя sphinxsearch
    su sphinxsearch -c 'crontab -e'

    Выбираем редактор и вводим такие таски
    12 */3 * * *  indexer --rotate topicsIndex > /dev/null 2>&1
    */50 * * * *  indexer --rotate commentsIndex > /dev/null 2>&1