Генерация URL для rest API

Для генерации адреса c целью доступа к API есть специальный метод

SUGAR.App.api.buildURL(
	module, // Строка, имя подуля (Calls,Accounts,Opportunities)
	action, // действие, параметр необязательный,
			// прилепляется в конец итогового URL
	attributes, // необязательный объект,
				// можно задать id записи, link и relatedId
	params // необязательный объект для дополнения адреса get переменными
)

К примеру для привязки существующего звонка к сделке — url должен быть следующего вида
/<module>/:record/link/:link_name/:remote_id
для получения такого результата параметры должны быть следующими

SUGAR.App.api.buildURL(
	'Accounts', // основной модуль
	'', // не нужен в данном случае
	{
		link : 'calls', // связанный модуль
		id : '123-456', // ид сделки (записи основного модуля)
		relatedId : '789-012' // ид звонка (записи связанного модуля)
	}
)

на выходе получаем следующий url:
rest/v10/Accounts/123-456/link/calls/789-012
его уже можно использовать в вызове методов rest API

Для случаев типа /<module>/filter/count — достаточно указать модуль и в качестве action — оставшуюся часть ссылки «filter/count»

SUGAR.App.api.buildURL('Accounts', 'filter/count')

Параметр params этого метода введен, видимо, на всякий случай, совершенно, правда, непонятно на какой.
Этот метод всегда работает в паре с SUGAR.App.api.call, который принимает объект data со всеми данными, которые необходимо передать на сервер, и сам уже решает куда помещать эти данные: в post или в get параметры.

Вызов метода rest API javascript

Вызов метода API бэкэнда осуществляется следующим методом javascript API

SUGAR.App.api.call(method, url, data, callbacks, options)

первый параметр method — это вопреки ожиданиям не HTTP метод, а CRUD action, который может принимать одно из значений:
— read (GET)
— create (POST)
— update (PUT)
— delete (DELETE)
В скобках указан HTTP метод, который придет в бэкенд, именно он должен быть указан в массиве регистрации метода API c ключом «reqType», к примеру для обновления записи (метод js api — «update», метод для PHP rest api — «PUT»)

public function registerApiRest() {
    return array(
        'saveSomething' => array(
	    'reqType' => 'PUT',
	    'path' => array(
                'Opportunities', 
                '?', 
                'save-something'
            ),
            'pathVars' => array(
                'module', 
                'id', 
                'method'
            ),
            'method' => 'saveSomething',
            'shortHelp' => 'save something for opportunity',
            'longHelp' => '...save-something.html',
    ),
    ...

Второй параметр — url
Указывать прямую ссылку — явно дурной тон, будем использовать для этого возможности js api, об этом в следующем посте
Третий параметр — data — привычный объект c данными, которые необходимо передать на сервер, к примеру

{
    summa: 10000,
    sales_stage: "work"
}

Четвертый параметр — callbacks — объект с функциями-коллбэками

{
    success: function(answer) {
        "Успешное завершение вызова, answer (при дефолтных параметрах) - объект";
    },
    error: function(error) {
        "Произошла какая-то ошибка, лучшее решение в этом случае - показать сообщение об ошибке и добавить какие-то рекомендации человеку, который возможно это увидит";
        App.alert.show('wrong_save', {level:'error',autoClose:false,messages:error.message+"\n Попробуйте перезагрузить страницу и попробовать заново, если не поможет - сообщите программисту."});
    },
    complete: function() {
        "Этот коллбэк отработает в любом случае, тут можно убрать блокировки на время загрузки"
    },
}

Ну и последний параметр — это объект с параметрами для совершения ajax запроса
Дефолтные параметры:

{
    url: null, // если url не указали вторым параметром - его можно указать здесь
    type: "GET", // тут можно указать HTTP метод напрямую
    dataType: 'json',
    headers: {},
    timeout: 30000, // 30 sec
    contentType: 'application/json'
}

Очень долго открывается папка в Windows 10

Начиная с windows 7 (windows 8 и 10) безумно долго открываются папки с видео, фильмами.
Еле-еле ползет в строке адреса заполняющая полоска и нажатие на крестик дело не ускоряет, ползунок останавливается и пропадает, но папку показывает пустую.
Лечится это дело очень просто, как оказалось.
В настройках папки тип содержимого меняем с Видео на Общие элементы и папка начинает открываться сразу, без этой жутко раздражающей паузы. Создание крупных значков миниатюр от этого ни капельки не страдает, показываются как положено.
folder_open_slow
Я так понял долго открывает папку потому, что за каким-то чертом, каждый раз при открытии папки винда читает медиаданные всех фильмов в этой папке, прежде чем начать хоть что-то показывать.

Белый экран в bitrix

Внезапно bitrix начал показывать белый экран на некоторых страницах и при входе в админку.
Много чего перепробовал, включение error_reporting и display_errors не помогает, пробовал вставлять в файлы инициализации, конфига, прологи, ничего не помогает.
Выход еле-еле нашелся, оказывается, в bitrix/.settings.php надо включить логирование ошибок, добавить элемент массива конфигурации:

return array (
	...
	'exception_handling' => 
		array (
			'value' => 
			array (
			'debug' => true,
			'handled_errors_types' => E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE & ~E_DEPRECATED,
			'exception_errors_types' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_USER_WARNING & ~E_USER_NOTICE & ~E_COMPILE_WARNING,
			'ignore_silence' => true,
			'assertion_throws_exception' => false,
			'assertion_error_type' => 256,
			'log' => array (
				'settings' => array (
					'file' => 'bitrix/modules/error.log',
					'log_size' => 1000000,
				),
			),
		),
		'readonly' => true,
	),
	...
);

После чего причину падения битрикса можно будет увидеть в файле лога bitrix/modules/error.log.
Стоит убедиться, что достаточно прав у веб пользователя для создания и записи в файл лога.
С большой степенью вероятности — причиной белого экрана будет неработоспособность какого-либо модуля. Пробуйте удалить папку модуля из bitrix/modules. И, после, установить этот модуль заново из админки.

Установка Sublime Text 2 на Debian 8 Jessie

На самом деле, все не так сложно
Копируем архив с сайта разработчика и разархивируем его

# bzip2 -d Sublime\ Text\ 2.0.2\ x64.tar.bz2
# tar -xvf Sublime\ Text\ 2.0.2\ x64.tar

В полученной папке ./Sublime Text 2 у нас уже рабочая программа, но сделаем все как положено: копируем содержимое этой папки в opt

# cp -R ./"Sublime Text 2" /opt/sublime-text-2/

И создаем все необходимые ссылки и ярлыки

# ln -s /opt/sublime-text-2 /usr/local/sublime-text-2
# ln -s /opt/sublime-text-2/sublime_text /usr/local/bin/subl2

Создаем ярлык приложения

# nano /usr/share/gnome/applications/subl2.desktop
Вставляем в редактор следующий текст:

[Desktop Entry]
Version=1.0
Name=Sublime Text 2
GenericName=Text Editor
Exec=/usr/local/bin/subl2
Terminal=false
Icon=/opt/sublime-text-2/Icon/48x48/sublime_text.png
Type=Application
Categories=TextEditor;IDE;Development;Office
X-Ayatana-Desktop-Shortcuts=NewWindow

[NewWindow Shortcut Group]
Name=New Window
Exec=/usr/local/bin/subl2 -n

После этого ярлык для запуска SublimeText 2 появляется в списке всех приложений в меню «Приложения» как минимум в категориях Программирование и Офис.
Если, конечно, вы активировали это расширение в настройках gnome.
В случае, если вы активировали опцию — показывать ярлыки на рабочем столе — то точно такой же файл subl2.desktop надо создать в домашней папке
~/»Рабочий стол»/subl2.desktop, тогда ярлык для запуска появится и на рабочем столе.

И, напоследок, будет совсем нелишним установить резвервную кодировку windows-1251 в Preferences: Settings — User
добавляем строку «fallback_encoding»: «Cyrillic (Windows 1251)», в основной блок

Как запустить службу redis?

После установки redis создается служба Redis Server, которая упорно отказывается стартовать, пишет: «Служба была запущена и затем остановлена. Некоторые службы автоматически останавливаются, если они не используются другими службами или программами».
Похоже, это связано с тем, что она устанавливается в Programm Files, и запускается от имени RedisService.
Достаточно поменять учетную запись, от которой пытается запуститься служба на LocalSystem и она начинает нормально запускатьcя.
Пуск->В поиск: «cmd»->На «cmd.exe» правой кнопкой мыши->запуск от имени администратора->

sc config redis obj= "LocalSystem"

->Enter

Автозавершение кода для phalconphp

Хотелось бы иметь простой доступ к списку методов некоторых сервисов и передаваемых в них параметров не заглядывая в документацию.
Конечно, из любого контроллера можно обратиться к стандартному сервису через переменную с соответствующим названием $this->tag, $this->url, автодополнение срабатывает как положено в любом нормальном IDE. Как настроить автодополнение для phalconphp для Netbeans?
Но в случае использования своих сервисов IDE уже молчит. Да и возникает необходимость обращаться как к своим, так и к стандартным сервисам phalcon не только из контроллеров.
В моделях возникает необходимость добавить методы получения данных из соответствующих таблиц, в случаях, когда критерии выборки из таблицы сложные, в этом случае неправильно пихать такой код в контроллер, тем более, когда получаем эти данные с такими критериями в нескольких местах одного, а то и нескольких контроллеров. При этом может возникнуть необходимость обратиться к методам сервисов: базы данных, acl.
К примеру, надо получить список задач:
проверяем, чтобы ответственный за выполнение задачи или постановщик совпадал с ИД текущего пользователя или он входил в список наблюдателей задачи;
обнуляем поля таблицы, для просмотра которых пользователей не имеет прав (обусловлено использованием dataTables — данные передаются по аякс и в данных должны присутствовать все столбцы).
Получается — из модели мы как минимум должны обратиться к методам сервисов auth (предпочитаю использовать отдельный сервис для данных пользователя, который умеет инициализироваться по ключу из кук, запомнить авторизацию в куках и забыть при выходе) и acl (\Phalcon\Acl\Adapter), в некоторых случаях еще возникает необходимость вызвать методы адаптера базы данных (\Phalcon\Db\Adapter\Pdo) или модель-менеджера (\Phalcon\Mvc\Model\Manager).
Можно, конечно, воспользоваться конструкцией вида:

\Phalcon\DI::getDefault()->getModelManager()
\Phalcon\DI::getDefault()->getAuth()
# или 
\Phalcon\DI::getDefault()->get('modelManager')
\Phalcon\DI::getDefault()->get('auth')

Но, вот незадача — в обоих случаях уже надо будет лезть в документацию, чтобы узнать точное название нужного метода и порядок передаваемых параметров. А хотелось бы, чтобы IDE сразу выдало подсказку для всех возможных методов.
Для начала: я предпочитаю при инициализации сервисов объявить глобальную функцию getDi():

/**
 * @return \Phalcon\DI\FactoryDefault
 */
function getDi() {
	static $di = null;
	if (!$di) {
		$di = new \Phalcon\DI\FactoryDefault();
	}
	return $di;
}

потому как не люблю лишнего нагромождения кода, которое создаст использование конструкции \Phalcon\DI::getDefault().
Далее, создаем папочку в проекте, к примеру my-phalcon.
И копируем туда phalcon-devtools\ide\{номер версии}\Phalcon\DI.php.
Вносим нужные изменения в этот файлик — добавляем вызов недостающих там сервисов:

namespace Phalcon {
	...
	class DI implements \Phalcon\DiInterface {
		...
		/**
		 * @return \Phalcon\Security
		 */
		public function getSecurity() {}
		/**
		 * @return \Handy\Models\Auth
		 */
		public function getAuth() {}
		/**
		 * @return \Phalcon\Acl\Adapter\Memory
		 */
		public function getAcl() {}
		/**
		 * @return \Phalcon\Db\Adapter\Pdo\Mysql
		 */
		public function getDb() {}
		/**
		 * @return \Phalcon\Tag
		 */
		public function getTag() {}
		...
		# ваши сервисы
		...

И, вуаля: автозавершение для всех доступных методов, всех нужных сервисов работает!
my-phalcon-di

Переменные среды в windows

Со времен windows 95 редактирование «Переменных среды» не меняется совершенно. Для некоторых программ приходится по роду работы дописывать пути в переменную Path — и нежелание разработчиков сделать редактирование переменных хоть чуть удобнее за более чем 20 лет, откровенно удивляет. С чем это связано — не могу взять в толк )
Если поставить тему «Классическая» — то разницы и вовсе не заметить.

fetchAll и bindTypes в phalconphp

Согласно документации описание метода fetchAll класса Phalcon\Db\Adapter\Pdo\Mysql выглядит так:

public array fetchAll (
    string $sqlQuery,  
    [int $fetchMode],
    [unknown $placeholders]
) inherited from Phalcon\Db\Adapter

подготовил запрос, включил туда

LIMIT :offset, :limit

массив bind:

$bind = array(
    'offset'=>$offset,
    'limit'=>$limit
);

Вызываю fetchAll

getDi()->getDb()->fetchAll(
    $sql, 
    \Phalcon\Db::FETCH_ASSOC, 
    $bind
);

— и на тебе:
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘ ‘0’, ’25’ ‘
Похоже целочисленные значения подставились в запрос как строки.
Пробую явно привести значения к целочисленному типу:

$bind = array(
    'offset'=>intval($offset), 
    'limit'=>intval($limit)
);

Нифига, все по-прежнему, та же самая ошибка.
Как оказалось, в официальной документации есть неточность, описание метода должно выглядеть так:

public array fetchAll (
    string $sqlQuery
    [, int $fetchMode]
    [, array $placeholders]
    [, array $types]
) inherited from Phalcon\Db\Adapter

Стоило лишь добавить в вызов четвертый параметр

$types = array(
    'limit' => \Phalcon\Db\Column::BIND_PARAM_INT,
    'offset' => \Phalcon\Db\Column::BIND_PARAM_INT
);
getDi()->getDb()->fetchAll(
    $sql,
    \Phalcon\Db::FETCH_ASSOC,
    $bind,
    $types
);

и все заработало.

Отчего падает phalconphp?

Буду дополнять список ситуаций, из-за которых phalcon падает без объяснения причин.

Просто отдает пустую страницу, если:

  1. Попытаться дать доступ к ресурсу, вызвав \Phalcon\Acl::allow, если ресурс или роль еще не добавлены