test
ТЗ на оживление микрокассы (разработка PHP-внутренностей)
22.11.2009 мои проекты
Итак, краткое описание проекта вы уже прочли на Free-Lance.ru, теперь ближе к делу.
Сперва описание API и скрипты: что-то вам понадобится обязательно, а что-то дано опционально — можете пользоваться, можете нет, лишь бы задача была выполнена быстрее и качественней.
- API для интеграции LiqPay. С примерами на PHP! Фактически можно просто выдрать куски кода и вставить в проект, совсем немного приложив мозг. Впрочем, мозг лучше прикладывать всегда и везде :)
- Мои PHP-функции. Дело в том, что я начинал уже делать «Визави», но не успеваю ничего. В комплект входят функции логина, проверки авторизации, отсылки писем, записи данных в файл, обёртка шаблоном, генерация пароля и даже намётки по функции, которая подготавливает формочку liqpay. Часть функций можно использовать как есть, часть требует доработки.
- PHP-класс Textile, используется для разметки текста и вывода HTML. Качайте обязательно от меня, т. к. официальная последняя версия содержала ошибки с оформлением списков. Багрепорт отправил, но неизвестно, исправили это или нет.
Ниже по тексту будут встречаться ещё ссылки, так что прошу читать внимательно, это может значительно сократить ваше время на разработку.
Пользовательский интерфейс
Всё уже готово, осталось только оживить его. Ниже список страниц, но не пугайтесь их количества, просто я предусмотрел как можно больше вариантов, даже некоторые страницы ошибок. HTML шаблон везде один и тот же.
http://brokenbrake.biz/stuff/VisaviPrototype/
Вот это всё и нужно оживить, чтобы работало как задумано.
Умная форма — определение и вывод цены
Форма (как для клиентов, так и в настройках у владельца) должна понимать всевозможные варианты написания цены: от официальных наименований валют до жаргонизмов. Регистр не должен иметь значения. Предварительный список соответствий такой:
Валюта в международном формате |
Возможные вариации |
Результат |
RUR |
рублей, руб., RUR, RUB, rubles, р. |
рублей |
UAH |
гривен, гр. UAH, грн., |
гривен |
EUR |
евро, евр., просто значок € перед или после цены, EUR, Euro, Evro (обрабатываем опечатки) |
евро |
USD |
значок $, USD, долларов, у.е., зелёных :), dollar*, долар (опечатки) |
долларов США |
Было много вопросов по этому функционалу, поэтому написал сам — http://pastie.org/716379. Просто используйте и всё.
Если вы придумаете больше вариантов — я буду рад как слон! :) Но лучше особо не увлекайтесь. В итоге форма должна просто преобразовать значение и выдать результат с учётом числительных. Пожалуйста, не перечисляйте тупо мои примеры, придумайте красивое универсальное регулярное выражение для определения валют.
В случае неудачного определения форма должна сообщить о том, что не поняла пользователя и предложить переписать сумму (при этом в поле ввода должна остаться лишь цифровая часть с пробелом).
Замечу, что внутри система должна оперировать только международными обозначениями, которые понимает LiqPay и почти все без исключения API. То есть «1000 рублей» в настроечном файле могут выглядеть примерно как sum=1000, currency=RUR.
Теперь про точки и запятые. Т. к. проект пока предназначен для Рунета, используем запятую в качестве разделителя десятичных знаков при отображении. Но форма должна одинаково хорошо понимать как запятую, так и точку. При этом внутри она должна оперировать числами с точкой, т. к. это принято, опять же, во всех API, да и сам PHP понимает лишь точку в качестве разделителя.
Суммы с тысячными и прочими должны округляться до сотых — это максимальная точность.
URLы
Прежде всего все URLы должны быть относительными, дистрибутив должен без проблем устанавливаться как в корень домена, так и в подкаталоги. Поэтому никакого абсолюта, пожалуйста. Далее список URLов, от корня проекта. (Кстати, буржуи назвали бы это URL namespaces?)
- / — Главная страница, именно отсюда пользователь начинает оплату.
- /?proof — Проверка введённых данных (вдруг мыло неправильное или сумма?). Здесь же конструируется и встраивается в страницу форма для LiqPay.
- /?thanks — Клиент сделал оплату, вернулся с LiqPay.
- /?adm — Основные настройки. Если владелец ещё не прошёл авторизацию ранее и в куках это не отмечено, выводится форма входа (и вообще на всех URL из /?adm*). Если же он авторизован и в куках есть значение страницы в панели отличное от /?adm, пусть происходит редирект на последнее действие в панели. Например к высылке нового счёта.
- /?adm=invoice — Выставить счёт клиенту из панели управления. По результатам после POST-запроса (если не было ошибок) могут быть два результата: сообщение об отправке счёта или выдача ссылки для ручной передачи.
- /?adm=pages — Редактировать текст страниц.
- /?adm=notifications — Настроить почтовые уведомления.
- /?adm=look — Сменить оформление (CSS и HTML).
- /?adm=access — Сменить пароль и/или почтовый адрес владельца.
- /?remind — Напомнить пароль (на самом деле сгенерировать). Страница доступна без авторизации.
- /?style — Выдача стиля CSS (не забудьте про правильные серверные заголовки).
- /liqpay.php — Обработчик запросов LiqPay.
- /install.php — Установщик.
Предполагаемая структура дистрибутива
- var/set.php — в этом файле хранятся все настройки, включая пользовательский шаблон и CSS. Я обычно использую для содержимого такого настроечного файла результат вывода удобной функции var_export($array, true). См. пример функции для записи настроек в моих функциях (ссылка дана выше).
- index.php — обрабатывает запросы к главной странице, а также работает с владельцем системы (настройки).
- liqpay.php — принимает сигнал от liqpay, и если подпись правильная, отправляет 2 почтовых уведомления о платеже: владельцу системы и совершившему платёж человеку.
- install.php — совершает установку системы, проверяет, возможна ли запись в каталог var. Для пользователя это выглядит вот так. Если вызывается после установки — сообщает, что повторная установка невозможна.
- installData.php — содержимое аналогично var/set.php, используется только при установке.
- template.html — умолчальный шаблон системы, используется внутри панели управления (всегда) и если в настроечном массиве значение HTML пустое.
- style.css — тоже, но для CSS.
- messages.php — файл со всей текстовой информацией для интерфейса, пригодный для удобного редактирования, перевода и добавления новых элементов. Названия переменных в нём должны быть логичными (семантичными), а не вида $word1, $word2. Скорей всего здесь же удобнее всего разместить варианты написания числительных (рубля, рублей, рубль).
Вроде бы всё по структуре. Если вы уверены, что лучше делать всё совсем иначе — предлагайте, давайте обсудим. Приоритет — создание качественного хорошего продукта, поэтому внимание к мелочам и профессионализм разработчика всегда приветствуется. Лишь бы это не затягивало разработку.
Обработка ошибок
С формами очень просто: если ошибка обнаружена, пусть выводится та же форма, но у label стоит class='ahtung' (в CSS для него прописан красный цвет) и к содержимому label добавляется краткий текст ошибки (или текстом ошибки замещается текст label). Пример — http://brokenbrake.biz/stuff/VisaviPrototype/validate_error.html Кстати, именно там текст ошибки выводится под полем ввода. Я понимаю, что это может быть неудобным, да и неоправданным — делайте так, как будет лучше на ваш взгляд.
Если ошибка без формы (например как тут), просто параграф с тем же классом.
Подробный список ошибок, которые нужно обрабатывать:
- неверный email на любых страницах;
- нераспознанный формат суммы оплаты;
- попытка установки, если система уже установлена;
- слишком низкая версия PHP, с которой система не сможет работать;
- неправильный пароль при входе;
- неправильный повтор пароля при установке или попытке сменить пароль;
- не введён актуальный пароль в разделе смены мыла/пароля;
- неизвестный системе email при попытке «вспомнить» пароль;
- невозможность выставить счёт отправкой письма;
- пустая тема письма в настройках уведомлений;
- отсутствие тега <vi:content /> в HTML-шаблоне;
- пожалуйста, на ваше усмотрение, если я что-то упустил.
Кроме того, хоть это не совсем ошибка, но в этом разделе уместно: необходимо выводить на главной вместо формочки сообщение о том, что микрокасса пока не настроена и приём денег невозможен, если владелец ещё не заполнил ID мерчанта и подпись от LiqPay в настройках.
Шаблоны HTML и CSS
По-умолчанию берутся template.html и style.css, кроме того, их содержимое подставляется в соответсвующие поля ввода, если в настройках по CSS и HTML пусто. Но даже если в настройках есть HTML и CSS, для панели управления остаются данные файлы.
В HTML система должна понимать три своих тега, причем распознавать их независимо от регистра и наличия/отсутствия закрывающего слэша. Вот эти теги:
- <vi:title /> — заголовок страницы (просто текст). На главной и «спасибной» (/?thanks) его содержимое должно выдёргиваться из текстильного h1 (вырезая возможные HTML-теги), а если его нет — подставляться умолчальное значение.
- <vi:style /> — заменяется на <link rel='stylesheet' href='./?style=time' />, где time является отметкой времени UNIX момента последнего изменения стиля из панели управления. Временная метка нужна чтобы браузеры клиентов гарантированно взяли новый стиль.
- <vi:content /> — собственно, всё содержимое, которое сейчас, в умолчальном шаблоне находится внутри body. Прежде всего это форма на главной, подтверждающая информация и подтверждение оплаты.
Почтовые уведомления
Если что, для справки рекомендую ознакомиться с небольшой статейкой, но я её уже давно читал и постоянно пользуюсь своей функцией отправки email, которая есть в скрипте-сборнике (ссылки были выше). Поэтому просто используйте это, чтобы не тратить лишнее время, функцию нужно лишь немного модифицировать.
Владелец «Визави» может сбросить поле подписи в настройках, сделать его пустым. Так вот, необходимо проверять эту ситуацию, и в таком случае подпись не ставить. Если же она есть, то нужно делать два перевода строки, символы -- и снова два перевода строки перед добавлением подписи. Такая подпись, например, в gmail корректно определяется и показывается сереньким цветом :)
Формат письма владельцу о совершенном платеже
Здесь и далее в квадратных скобках мои примечания о формировании письма, содержимое квадратных скобок не должно в нём содержаться.
subject: «Визави» сообщает о новом платеже
body:
Сумма: 1000 рублей.
Email: example@example.com.
Телефон: +7 NNN 203 7777. [Обратите внимание, номер разделяется пробелами для удобства восприятия, хотя LiqPay выдаёт его слитно]
Оплата произведена с карты. [или со счёта LiqPay]
Формат уведомления оплатившему
subject: Подтверждение оплаты
body: Здравствуйте.
Вы только что совершили оплату за услугу или продукт на сайте example.com. Принятая сумма 1000 рублей, оплата произведена с карты [или со счёта Liqpay].
Спасибо за платёж! Получатель также получил уведомление.
— [подпись только если есть в настройках]
Микрокасса «Визави»
http://brokenbrake.biz/Visavi/
Формат письма-счёта
subject: Пожалуйста, оплатите счёт [настраивается в панели]
body: [Текст сообщения получателю]
Сумма для оплаты: 1000 рублей.
[здесь текст обоснования счёта, причём если он с маленькой буквы и без точки (так будет в большинстве случаев), поставить точку и повысить букву. Не забывайте про mb_string. Если mb_string вдруг нету (проверять), тогда вместо повышения регистра подставлять «Основание для счёта:» с пробелом]
Для оплаты пройдите по ссылке —
[здесь URL, о его формировании ниже]
— [подпись только если есть в настройках]
Микрокасса «Визави»
http://brokenbrake.biz/Visavi/
URL для выставления счёта
Прочитайте инструкцию, и вам всё станет понятно. Замечу только, что приниматься должны действительно как сокращённые варианты, так и полные (desc, description). Так, на всякий случай.
Требования и замечания
- Сейчас будет длинное предложение :) Прежде всего я жду современный лаконичный удобный код PHP5 c понятными комментариями, в котором сможет быстро разобраться любой программист. Продукт с открытым исходным кодом и я не хочу за него краснеть. Оформление должно быть отделено от программного кода.
- Продукт будет продаваться, поэтому в дистрибутиве не должны присутствовать библиотеки с сомнительной запрещающей что-то лицензией. MIT — хорошо, но лучше всего если вы всё напишете самостоятельно, без использования потенциально опасных (в лицензионном смысле) решений.
- Всё в UTF-8! И не забудьте про заголовки, т. к. некоторые отвратительные сервера настроены по-умолчанию отдавать в заголовке кодировку cp1251, а для браузера приоритет серверного заголовка, к сожалению, выше, чем указание кодировки в метатеге HTML.
- Пожалуйста, не увлекайтесь изобретанием различных велосипедов, используйте максимально лаконичные и удобные решения. Напирмер, для валидации email есть удобнейшая функция filter_var, именно её и стоит использовать. А у кого версия PHP на сервере ниже 5.2.0 — сами себе злобные Буратино, пусть обновляются :) В общем, наверно вы уже поняли, что я за прогресс и всячески приветствую желание разработчика использовать самые современные технологии.
- Не забывайте, что могут быть включены/отключены magic_quotes на сервере, но на работе «Визави» это не должно складываться — я не хотел бы видеть обратные слеши нигде. Извините, если некоторые пункты здесь для вас очевидны, но лучше немного избыточное ТЗ, чем ограниченное и чреватое непониманием и переделками, правда же?
- Наименования валют должны правильно склоняться, по-русски. То есть я буду зол, если «Визави» выдаст мне что-то вроде «1002 рублей», как это делают многие CMS. Давайте говорить по-русски. Опять же, не изобретайте велосипед, вот вам в помощь удобная проверенная функция — http://mcaizer.habrahabr.ru/blog/11555/.
- В панели управления при выставлении счёта в поля цены и цели оплаты подставляются умолчальные значения, которые настраиваются в соотсветствующем разделе. Ну а изначально они берутся из installData.php, не внедряйте никакие умолчальные значения в код.
- Важно! Впрочем, важны все пункты. Так вот, помните: любой текст в интерфейсе пользователя, включая ошибки, должен считываться с файла messages.php, не встраивайте никакие сообщения в код.
- В прототипе мне лень было изменять title в HTML, но он на самом деле везде разный в зависимости от настроек. Заголовок страницы должен формироваться так: «Визави» — текст заголовка h1 из шаблона».
- Обратите внимание! В шаблоне панели управления, там где выставляется счёт нет кнопочки «сохранить» на панели. Так надо, это сделано специально. Вместо этого есть две кнопки внизу формы, результат обработки которых здесь и тут соответственно. Это если нет ошибок, если ошибки есть — выводятся, как было написано выше в разделе «обработка ошибок». Не забудьте, что для варианта со ссылкой в URL ссылочки нужно экранировать амперсанды, а в textarea — нет. Ну и если знаете JS, там можно было бы сделать простенький скриптик автоматического выделения содержимого поля со ссылкой, это было бы удобно для пользователя.
- Вычисление высоты textarea. Важный пункт, напрямую влияющий на удобство пользования системой. Во-первых, у textarea для настройки текста страниц и оформления должен быть какой-то минимум, от трёх строк, например. Чтобы они не схлопывались, если кто-то решит удалить весь текст. Во-вторых, вычислять высоту для полей с CSS и HTML просто — по количеству строк + 2-3 строчки. Именно так и делайте для этих полей. А вот для текстовых полей страниц с Textile-разметкой прошу использовать мою функцию, т. к. я уже потратил время на эксперименты с другим проектом и добился неплохих результатов. Код здесь — http://pastie.org/709281.
- Обратите внимание, в меню прописывается class='current' для актуального пункта. Не знаю, какую-то простенькую функцию генерации меню надо делать, наверно.
- Думаю, прием всех полей с форм стоит пропускать через trim(), чтобы из-за случайного пробела не было проблем.
- Если пользователь заходит не по конкретной странице внутри /?adm*, а просто /?adm, то он должен попадать на последнюю страницу в панели управления, с которой работал, она должна запоминаться в куках. Это должно быть удобно.
- Прошу с HTML и CSS сильно не вольничать, все страницы буду проверять валидатором и вообще качество кода. Лучший вариант — просто всё делать полностью по моим шаблонам из прототипа.
- Для тестирования вам вполне должно хватить 5 центов, которые дарит LiqPay при подключении, мне по крайней мере хватило, когда я подключал мерчант самостоятельно. Но если что, не стесняйтесь спросить, кину большие суммы, чтобы можно было затестироваться при желании :)
- Пожалуйста, не забывайте, что продукт всё же предназначен для работы с деньгами, поэтому вы должны особое значение придавать безопасности. Не должно быть такого, чтобы хакер каким-нибудь особым запросом вдруг взял и сменил ID мерчанта и подпись, например. Или сменил текст на главной. В общем, прошу, будьте внимательны при написании кода.
Уфф… вроде бы всё? Я постараюсь быть онлайн всё время, сколько вы будете программировать, поэтому со мной можно будет быстро связаться. Но только почтой или чатом в gmail, ICQ я не пользуюсь, «Скайпом» тоже. Но на любые ваши вопросы я постараюсь ответить максимально оперативно.
Комментирование этой статьи закрыто.
« Daos: настройка в панели AvisoSMS
Эра цифровой свободы »
Это пиздец на не т.з. :)
1) Зачем навязывать разработчику какие-то средства типа этого Textile?
Сделать то нужно быстро и дешево. Никто не захочет за такие деньги изучать что-то помимо своего стандартного набора инструментов, который повседневно используется.
2)зачем навязывать структуру проекта?
Опять же, вы мешаете этим исполнителю использовать свои наработки и продумать нормальную архитектуру приложения.
3)Умная форма — это вообще пиздец. Так не делают, разве что если есть масса денег, времени и хочется побаловаться
4) Шаблоны HTML и CSS — неграмотно и опять усложняем
….
В общем, я могу еще долго продолжать. Тут и Getting Real не поможет ) Кстати, это ты тоже зря насчет требования к прочтению этой книги от исполнителя) В ответ могу посоветовать что-то почитать по project-менеджменту и составлению т.з. :)
p.s.: Если бы не было цели сэкономить и сделать все быстро — к таким требованиям можно было бы не придираться конечно, но тут просто ты сам себе противоречишь.
Textile прикручивается одной единственной строчкой и при этом даёт весь функционал для разметки текста. Его не нужно изучать.
Структура навязывается не жёстко, там же написано. Если есть доводы в пользу изменения структуры, всё обсуждается.
Замечание про умную форму — это вообще пиздец, да, согласен. Пиздец, потому что даже я, любитель, легко могу сделать этот функционал за пару часов. Поэтому не надо мне рассказывать про массу денег и времени. Мне такие разработчики, которые не могут осилить простейшую задачу не нужны, спасибо.
Шаблоны в этом проекте необходимы, и про грамотность доводы без аргументов вообще не принимаются.
Ну вот, вы(можно в дальнейшем на ты?) сказали, что по поводу умной формы для ввода цены — вы можете сами сделать этот функционал за пару часов. Где-то так оно и есть на самом деле, можно конечно это и за час сделать и быстрее, но допустим, что в среднем это займет 2 часа.
Час работы хорошего php-программиста — 10$.
Вы хотите чтобы все вам сделали за 35$ (на фри-лансе написано).
При таком раскладе на умную форму для ввода цены уйдет 60$ вашего бюджена.
Это при том, что преимущества «ввода цены в любом формате, хоть сленгом» совсем не очевидна — кому-то было бы проще ввести цифрами и просто выбрать валюту из выпадающего списка, а во вторых, всегда можно придумать такой сленг, который ваша «умная форма» некорректно распарсит.
Т. е. получаем потерю 60% бюджета на ровном месте ради совсем неочевидных преимуществ :)
Я не говорю что нужно за это задание платить 100-200-500$, вы делаете правильно для своего кармана, что называете низкую цену и это ок. Шанс найти исполнителя есть, тем более на фри-лансе работают за еду и плюсики. Я бы поступил точно так же. Я только хочу сказать, что Т.З. у вас это пиздец. Не для исполнителя. Для вашего бюджета, вы не экономите свои деньги.
Я вот тоже раньше давал макеты на верстку по 20-30 баксов на фриланс и мне все отлично делали, а пару неделек назад случилась полная жопа: никто не захотел браться за достаточно сложный трехколоночный резиновый макет за такую цену. Мог бы сделать сам, но согласился заплатить 50$ верстальщику из Кыргызии. В результате — куча гемора, потраченных нервов, заплачены деньги, сорваны все сроки и в верстке после посадки ее на админку найдено такое невъебенное количество багов, что лучше бы я сам верстал — потратил бы раза в 4 меньше нервов, времени, получил бы нормальный результат и не тратил бы деньги. Вот так вот.
На фри-лансе раз на раз не приходится. Безопасная сделка кстати, это все-таки респект.
Ко мне всегда лучше на «ты», так что всё ОК. А функцию я уже написал и заняло это гораздо меньше времени. Про бюджет я тоже писал, что всё обсуждабельно, фрилансеры предлагают свои цены.
P.S. ОК, час работы хорошего программиста стоит $10, допустим. Хотя я не понимаю этих почасовых расценок, просто не понимаю. Так вот, я считаю, что хороший программист никогда не назвал бы сложной настолько примитивную задачу.
Тормоз, твоя функция не разбирает «10 баксов» :)
Спасибо, теперь разбирает. 30 секунд ушло на это.
Я уже беру 10 ойро за час работы, а вернее 120грн, ибо работа у меня комплексная и обычно, задания делаю быстро.
Функция блеск, разминка мозгов и радость глазу :) кросспостнул ;)
Deerua, хочешь ещё разминочку маленькую? Сделай у себя форму комментов человеческую, а то она такая невежливая, зараза… :)
Ухты, спасибо. Я ПХП пока только изучаю. Очень интересно поковырять твои функции :)
Согласен с Nayjest, умная форма с точки зрения юзабилити и программиста — бесполезна и даже вредна. Программирование строго формальная вещь, если пользователь введёт «10 баксаф», что будешь делать? А сам пользователь просто растеряется: «что мне вводить, чтобы не ошибиться?». Поле ввода суммы + комбобокс выбора валюты — так делают все, и не потому что это просто, а потому что правильно. Хоть комментарий и запоздал, но ссылка сюда есть в посте про Йерку. Сама Йерка, кстати, хороший пример говнокода, без обид.
Да, теперь тоже склоняюсь к тому, что решение с выпадающим списком валют было бы более правильным. Надо было выпендриться :)
Насчёт говнокода, так это очень относительно. Пусть я не суперпрограммист, но всё же и далеко не говнокодер, уверен в этом. Тем более, расту, сейчас я уже и «Йерку» и «Визави», всё иначе делал бы, лучше.
В общем, я уже писал где-то, отвечая на подобные же вбросы: если критикуешь, аргументируй. Вот про выбор валют я согласился, в том числе и потому что аргументы действительно разумные.