ВВЕДЕНИЕ
Сегодняшняя революция в информационных технологиях изменяет традиционные представления о ведении бизнеса и рыночной модели экономики вообще. Электронная коммерция уравнивает шансы в привычной конкурентной борьбе, позволяя как крупным, так и мелким компаниям состязаться на равных в качестве, цене, ассортименте продукции. При затратах, равных стоимости рекламного объявления в местной газете, она дает торговым организациям доступ к мировому рынку, недоступному для малых компаний никакими другими средствами. Одним из элементов современной рыночной экономики являются электронные аукционы, которые позволяют покупать товары как в частных, так и бизнес-целях по оптимальным в каком-то смысле ценовым предложениям.
Данный дипломный проект посвящен разработке клиент-серверного веб-приложения «Интернет-аукцион».
Целью данного дипломного проекта является разработка клиент-серверного приложения «Интернет-аукцион».
Задачами дипломного проекта являются:
изучить инструментальные средства для создания веб-приложений;
изучить особенности выбранных интернет-аукционов;
изучить язык объектного анализа и проектирования UML;
разработать веб-приложение интернет-аукциона;
осуществить наполнение и тестирование разработанного интернет-магазина;
Объектом исследования дипломного проекта является веб-приложение «Интернет-аукцион».
В данном дипломном проекте имеются следующие разделы:
Обзор инструментальных средств для создания клиент-серверных веб-приложений и языка объектного анализа и проектирования UML.
Проектирование веб-приложения «Интернет-аукцион».
Разработка веб-приложения «Интернет-аукцион».
Дипломный проект насчитывает 212 страниц, 21 источник, 35 рисунков, 12 листингов.
1. Обзор инструмента РИЯ для создания клиент-серверных веб-приложений
1.1 Концепция Web 2.0
Раньше доступ в Интернет можно было получить только с компьютеров. Потом в Интернет стали выходить с мобильных телефонов. Сейчас к Сети подключились мультимедийные плееры, устройства чтения электронных книг и телевизоры.
Что требуется от современного Web-сайта? Соблюдение при создании трех несложных правил:
Строго соблюдать все интернет-стандарты.
Тщательно продумать наполнение Web-страниц.
Позаботиться о доступности Web-страниц.
Рассмотрим их подробнее. Интернет грозится прийти на самые разные устройства, которые могут быть основаны на разных аппаратных и программных платформах, зачастую сильно отличающихся друг от друга. Так, персональные компьютеры построены на аппаратной платформе Intel и программной платформе Microsoft Windows (по крайней мере, большинство). Мобильный телефон автора основан на аппаратно-программной платформе Samsung.
Одно объединяет все это аппаратно-программное многообразие - соответствие интернет-стандартам. Иначе устройства в лучшем случае будут отображать Web-страницы неправильно, в худшем - вообще не будут работать.
Из этого следует первое правило из перечисленных ранее - Web-дизайнеры при создании Web-страниц обязаны строго придерживаться современных интернет-стандартов, чтобы их творения одинаково (ну, или почти одинаково) отображались на всех устройствах. Первое правило также требует отказа от устаревших и закрытых, фирменных интернет-технологий. С устаревшими технологиями все понятно: старье - не помощник новому. Закрытые же технологии неудобны тем, что зачастую контролируются единственной фирмой, которая единолично 'заказывает музыку' и далеко не всегда прислушивается к мнению интернет-сообщества. К таким технологиям относятся, в частности, Adobe Flash и Microsoft ActiveX.
Открытыми интернет-стандартами, в том числе и Web-стандартами, занимается организация World Wide Web Consortium (Консорциум Всемирной паутины), или сокращенно W3C. Она разрабатывает стандарты, согласует их с требованиями участников рынка и публикует на своем Web-сайте http://www.w3.org. Все опубликованные там стандарты обязательны к применению.
Интернет когда-то начинался как сеть ученых, которым было нужно обмениваться результатами исследований. А что представляли собой эти результаты? В основном, текст, возможно, с иллюстрациями. Ученые - публика в этом смысле невзыскательная, им вполне хватало скромных возможностей тогдашнего WWW. Теперь же абсолютное большинство пользователей Интернета - обычные обыватели. Им мало простого текста с парой картинок, им подавай хорошо оформленный текст, музыку и видео. Они требовательнее первых обитателей Сети.
Отсюда вытекает второе правило - Web-дизайнеры должны заботиться о полноте и удобстве наполнения Web-страниц.
Структура Web-страниц должна быть хорошо продумана, чтобы посетитель сразу смог найти на них все, что ему нужно.
Web-страницы должны легко читаться и не 'резать' глаза.
К важным материалам желательно привлечь внимание посетителя, а маловажные скрыть. В этом могут помочь динамические элементы: раскрывающиеся при щелчке мышью абзацы, гиперссылки, выделяющиеся при наведении курсора мыши, и пр.
Если Web-сайт посвящен музыке или видео, все это должно быть доступно для воспроизведения прямо на его Web-страницах, без загрузки.
Одним словом - все для удобства посетителя! (Пожалуй, это правило следовало бы поставить в начале списка...)
Интернет грозится прийти на самые разные устройства с различными характеристиками: быстродействием процессора, объемом памяти, разрешением экрана, скоростью доступа к Сети. Но все они должны обеспечивать единообразный вывод Web-страниц. Как этого достигнуть?
Вот и третье правило - Web-дизайнеры должны заботиться о доступности Web-страниц.
Web-страницы следует делать как можно более компактными. Чем компактнее файл, тем быстрее он загружается по сети - это аксиома.
Web-страницы не должны быть чересчур сложными. Чем сложнее Web-страница, тем больше времени и системных ресурсов требует ее обработка и вывод.
Web-страницы не должны требовать для отображения никакого дополнительного программного обеспечения. В идеале для их вывода достаточно только Web-обозревателя.
Но как эти правила реализуются на практике? Давайте откроем какой-нибудь современный Web-сайт, например, принадлежащий организации W3C. Его можно найти по интернет-адресу http://www.w3.org. Сайт приведен на рисунке 1.1.
Из дизайна сайта можно сделать следующие выводы:
Web-сайт создан с учетом всех современных интернет-стандартов. Он отображается во всех Web-обозревателях практически одинаково.
Web-сайт не использует ни устаревших, ни закрытых интернет-технологий.
Структура Web-страниц исключительно ясна - мы можем без проблем найти все, что нужно. Слева находится набор гиперссылок, ведущих на другие Web-страницы Web-сайта, посередине - список новостей и гиперссылки на избранные статьи, справа - гиперссылки на дополнительные материалы.
Рис. 1.1 - Сайт консорциума w3c.org
Web-страница прекрасно читается. Тонкий шрифт без засечек, спокойная серо-голубая цветовая гамма, тонкие рамочки со скругленными углами, минимум графики - ничто не бросается в глаза.
Имеется видеоролик.
Web-страница быстро загружается и мгновенно выводится на экран.
Web-страница ничего не требует для своего вывода, кроме Web-обозревателя.
Налицо и соблюдение стандартов, и наполнение, и доступность. Давайте еще раз обратимся к рассмотренным ранее правилам и немного расширим их:
При создании Web-страниц следует придерживаться современных интернет стандартов. При этом нужно полностью отказаться от устаревших и закрытых интернет-технологий, как не укладывающихся в современную парадигму Web-дизайна и зачастую не поддерживаемых всеми Web-обозревателями.
Особое внимание нужно обратить на структуру и наполнение Web-страниц.
Структура Web-страниц должна быть максимально простой, а наполнение - достаточно богатым, чтобы посетитель быстро нашел нужную ему информацию. Кроме того, необходимо создавать Web-страницы так, чтобы дизайн не мешал восприятию информации.
Web-страницы обязательно следует делать максимально доступными на любых устройствах. Web-страницы должны быстро загружаться и выводиться на экран. Также Web-страницы не должны требовать для отображения никакого дополнительного программного обеспечения.
Фактически здесь мы привели постулаты так называемой концепции Web 2.0. Это список правил, которым должен удовлетворять любой Web-сайт, претендующий на звание современного. Образно выражаясь, это флаг, который совместно несут труженики Web-индустрии, шагая в ногу со временем.
Также концепция Web 2.0 предусматривает четыре принципа, являющиеся 'передним краем' Web-дизайна. Пока еще очень мало Web-сайтов им следует (и 'домашний' Web-сайт W3C, увы, не исключение...). Рассмотрим их по порядку.
Принцип первый - разделение содержимого, представления и поведения Web-страницы. Здесь содержимое - это информация, которая выводится на Web-странице, представление описывает формат вывода этой информации, а поведение - реакцию Web-страницы или отдельных ее элементов на действия посетителя. Благодаря их разделению мы сможем править, скажем, содержимое, не затрагивая представление и поведение, или поручать создание содержимого, представления и поведения разным людям.
Принцип второй - подгружаемое содержимое. Вместо того чтобы обновлять всю Web-страницу в ответ на щелчок на гиперссылке, мы можем подгружать только ее часть, содержащую необходимую информацию. Это сильно уменьшит объем передаваемой по сети информации (сетевой трафик) и позволит выполнять какие-либо действия с данными после их подгрузки.
Принцип третий - генерируемое содержимое. Какая-то часть Web-страницы может не загружаться по сети, а генерироваться прямо на месте, в Web-обозревателе. Так мы еще сильнее сократим сетевой трафик.
Принцип четвертый - семантическая разметка данных. Она позволит нам связать выводимые на Web-страницу данные согласно каким-либо правилам. Например, мы можем семантически связать страницы справочника по HTML, и посетитель, загрузив какую-либо страницу, сможет сразу же перейти на связанные с ней страницы, содержащие дополнительные или родственные сведения.
В качестве примера Web-сайта, реализующего эти четыре принципа, можно привести Web-сайт, позволяющий загрузить библиотеку Ext JS, расположенный по интернет-адресу http://www.sencha.com/ и показанный на рисунке 1.2. Особенности данного сайта следующие:
Содержимое, представление и поведение составляющих его Web-страниц хранится отдельно, в разных файлах.
При переходах с одной статьи справочника на другую подгружается только сам текст статьи. Остальные части Web-страницы, в частности иерархический список статей, остаются неизменными.
После загрузки текста статьи на его основе генерируется окончательное ее представление. Фактически мы имеем генерируемое содержимое.
Статьи справочника связаны друг с другом семантически. Эти связи используются для генерирования гиперссылок на 'родственные' статьи.
Рис. 1.2 - Сайт Sencha c библиотекой Ext JS
1.2 Язык разметки HTML5
Для форматирования содержимого Web-страниц применяется особый язык - HTML (HyperText Markup Language, язык гипертекстовой разметки). С помощью команд - тегов - этого языка создают и абзацы текста, и заголовки, и врезки, и даже таблицы. Первая версия языка HTML появилась в 1992 году [1, 2, 3, 4, 5].
Язык HTML и его теги. Изучать HTML лучше всего на примере. Так что давайте сразу же создадим нашу первую Web-страничку.
Это позволит нам лучше познакомиться с HTML. Откроем Блокнот и наберем в нем текст (или, как говорят бывалые программисты, код), приведенный в следующем листинге.
<!DOCTYPE html>
<HTML>
<HEAD>
<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=utf-8'>
<TITLE>Пример Web-страницы</TITLE>
</HEAD>
<BODY>
<H1>Справочник по HTML</H1>
<P>Приветствуем на нашем Web-сайте всех, кто занимается Web-дизайном!
Здесь вы сможете найти информацию обо всех интернет-технологиях, применяемых при создании Web-страниц. В частности, о языке
<STRONG>HTML</STRONG>.</P>
</BODY>
</HTML>
Создана Web-страница, содержащую заголовок, абзац текста, который автоматически разбивается на строки и содержит фрагмент текста, выделенный полужирным шрифтом (аббревиатура 'HTML').
Пока что ограничимся небольшим фрагментом HTML-кода.
Листинг 1.2
<H1>Справочник по HTML</H1>
<P>Приветствуем на нашем Web-сайте всех, кто занимается Web-дизайном!
Здесь вы сможете найти информацию обо всех интернет-технологиях, применяемых при создании Web-страниц. В частности, о языке
<STRONG>HTML</STRONG>.</P>
Здесь мы видим текст заголовка и абзаца. И еще символы < и > . Рассмотрим смысл этих символов.
Это и есть теги HTML, о которых упоминалось ранее. Они превращают тот или иной фрагмент HTML-кода в определенный элемент Web-страницы: абзац, заголовок или текст, выделенный полужирным шрифтом.
Начнем с тегов <H1> и </H1> , поскольку они идут первыми. Эти теги превращают фрагмент текста, находящийся между ними, в заголовок. Тег <H1> помечает начало фрагмента, на который распространяется действие тега, и называется открывающим. А тег </H1> устанавливает конец 'охватываемого' фрагмента и называется закрывающим. Что касается самого фрагмента, заключенного между открывающим и закрывающим тегами, то он называется содержимым тега. Именно к содержимому применяется действие тега.
Все теги HTML представляют собой символы < и > , внутри которых находится имя тега, определяющее назначение тега. Закрывающий тег должен иметь то же имя, что и открывающий; единственное отличие закрывающего тега -- символ / , который ставится между символом < и именем тега.
Рассмотренные нами теги <H1> и </H1> в HTML фактически считаются одним тегом <H1> . Такой тег называется парным.
Парный тег <P> создает на Web-странице абзац; содержимое тега станет текстом этого абзаца. Такой абзац будет отображаться с отступами сверху и снизу. Если он полностью помещается по ширине в окне Web-обозревателя, то отобразится в одну строку; в противном случае сам Web-обозреватель разобьет его на несколько более коротких строк. (То же справедливо и для заголовка.)
Парный тег <STRONG> выводит свое содержимое полужирным шрифтом. Как мы видим, тег <STRONG> вложен внутрь содержимого тега <P> . Это значит, что содержимое тега <STRONG> будет отображаться как часть абзаца (тега <P> ).
Давайте выделим слова 'Web-дизайном' курсивом. Для этого поместим соответствующий фрагмент текста абзаца в парный тег <EM> :
<P>Приветствуем на нашем Web-сайте всех, кто занимается
<EM>Web-дизайном</EM>! Здесь вы сможете найти информацию обо всех
Сохраним исправленную Web-страницу и обновим содержимое окна Web-обозревателя, нажав клавишу <F5>.
Осталось рассмотреть важнейшие правила, согласно которым пишется HTML-код.
Имена тегов можно писать как прописными (большими), так и строчными (малыми) буквами. Традиционно в языке HTML имена тегов пишут прописными буквами.
Между символами < , > , / и именами тегов, а также внутри имен тегов не допускаются пробелы и переносы строк.
В обычном тексте, не являющемся тегом, не должны присутствовать символы < и > . (Эти символы называют недопустимыми.) В противном случае Web-обозреватель сочтет фрагмент текста, где встречается один из этих символов, тегом и отобразит Web-страницу некорректно.
Вложенность тегов. Если мы снова посмотрим на приведенный в предыдущем листинге фрагмент HTML-кода, то заметим, что одни теги вложены в другие. Так, тег <STRONG> вложен в тег <P> , являясь частью его содержимого. Тег <P> , в свою очередь, вложен в тег <BODY> , а тот -- в 'глобальный' тег <HTML> . (Теги <BODY> и <HTML> мы рассмотрим чуть позже.) Такая вложенность тегов в HTML -- обычное явление.
Когда Web-обозреватель встречает тег, вложенный в другой тег, он как бы накладывает действие 'внутреннего' тега на эффект 'внешнего'. Так, действие тега <STRONG> будет наложено на действие тега <P> , и фрагмент абзаца окажется выделенным полужирным шрифтом, при этом оставаясь частью этого абзаца.
Давайте для примера текст 'Web-дизайн', который мы недавно поместили в тег <EM> , заключим еще и в тег <STRONG> .
<P>Приветствуем на нашем Web-сайте всех, кто занимается
<EM><STRONG>Web-дизайном</STRONG></EM>! Здесь вы сможете найти
. . .
В этом случае данный текст будет выделен полужирным курсивом. Иными словами, действие тега <STRONG> будет наложено на действие тега <EM>.
Порядок следования закрывающих тегов должен быть обратным тому, в котором следуют теги открывающие. Говоря иначе, теги со всем их содержимым должны полностью вкладываться в другие теги, не оставляя 'хвостов' снаружи. Если же мы нарушим это правило и напишем такой HTML-код (обратите внимание на специально перепутанный порядок следования открывающих тегов):
<P>Приветствуем на нашем Web-сайте всех, кто занимается
<EM><STRONG>Web-дизайном</EM></STRONG>! Здесь вы сможете найти
. . .
Web-обозреватель может отобразить нашу Web-страницу неправильно. Нужно сказать, что современные Web-обозреватели 'умеют' исправлять мелкие ошибки Web-дизайнера.
Осталось выучить несколько новых терминов. Тег, в который непосредственно вложен данный тег, называется родительским, или родителем. В свою очередь, тег, вложенный в данный тег, называется дочерним, или потомком. Так, для тега <EM> в приведенном далее примере тег <P> - родительский, а тег <STRONG> - дочерний. Любой тег может иметь сколько угодно дочерних тегов, но только один родительский (что, впрочем, понятно - не может же он быть непосредственно вложен одновременно в два тега).
Элемент Web-страницы, в который вложен элемент, создаваемый данным тегом, называется родительским, или родителем. А элемент Web-страницы, который вложен в данный элемент, - дочерним, или потомком. То же самое, что и в случае тегов.
Уровень вложенности того или иного тега показывает количество тегов, в которые он последовательно вложен. Если принять за точку отсчета тег <P> , то тег <EM> будет иметь первый уровень вложенности, т. к. он вложен непосредственно в тег <P> .
Тег <STRONG> же будет иметь второй уровень вложенности, поскольку он вложен в тег <EM> , а тот, в свою очередь, - в тег <P> . В сложных же Web-страницах уровень вложенности иных тегов может составлять несколько десятков.
Уровень вложенности тегов в HTML-коде обозначают с помощью отступов, которые ставят слева от соответствующего тега и создают с помощью пробелов. На отображение Web-страницы они никак не влияют.
<BODY>
<H1>Справочник по HTML</H1>
<P>Приветствуем на нашем Web-сайте всех, кто занимается Web-дизайном!
Здесь вы сможете найти информацию обо всех интернет-технологиях, применяемых при создании Web-страниц. В частности, о языке
<STRONG>HTML</STRONG>.</P>
</BODY>
Здесь сразу видно, что теги <H1> и <P> вложены в тег <BODY> , - видно по отступам.
Секции Web-страницы. Снова вернемся в полному HTML-коду нашей Web-странички. Мысленно удалим из него уже рассмотренный фрагмент.
<!DOCTYPE html>
<HTML>
<HEAD>
<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=utf-8'>
<TITLE>Пример Web-страницы</TITLE>
</HEAD>
<BODY>
. . .
</BODY>
</HTML>
Здесь применены несколько тегов, которые нам не знакомы. Это так называемые невидимые теги - теги, содержимое которых никак не отображается Web-обозревателем. Они занимаются тем, что хранят сведения о параметрах самой Web-страницы и делят ее на две секции, имеющие принципиально разное назначение. Секция тела Web-страницы находится внутри парного тега <BODY> . Она описывает само содержимое Web-страницы, то, что будет выведено на экран. Именно секцию тела мы рассматривали в предыдущих разделах.
А в парном теге <HEAD> находится секция заголовка Web-страницы. (Не путать с заголовком, который создается с помощью тега <H1> !) В эту секцию помещают сведения о параметрах Web-страницы, не отображаемые на экране и предназначенные исключительно для Web-обозревателя.
И заголовок, и тело Web-страницы находятся внутри парного тега <HTML> , который расположен на самом высшем (нулевом) уровне вложенности и не имеет родителя.
Любая Web-страница должна быть правильно отформатирована: иметь секции заголовка и тела и все соответствующие им теги. Только в таком случае она будет считаться корректной с точки зрения стандартов HTML.
Метаданные и тип Web-страницы. Вернемся к сведениям о параметрах Web-страницы, которые находятся в секции ее заголовка. Что это за параметры? И что они задают?
Сначала введем еще пару терминов. Параметры Web-страницы, не отображаемые на экране и предназначенные для Web-обозревателя, назовем метаданными. Это своего рода данные, описывающие другие данные, в нашем случае -- Web-страницу. А HTML-теги, которые задают метаданные, называются метатегами.
Прежде всего, в метаданные входит название Web-страницы. Оно отображается в заголовке окна Web-обозревателя, где выводится содержимое данной Web-страницы, и хранится в 'истории' (списке посещенных к настоящему времени Web-страниц). Название помещается в парный тег <TITLE> и располагается в секции заголовка Web-страницы:
<HEAD>
. . .
<TITLE>Пример Web-страницы</TITLE>
</HEAD>
Далее, обычно в секции заголовка расположен особый метатег, задающий кодировку, в которой сохранена Web-страница.
<META> :
<HEAD>
<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=utf-8'>
. . .
</HEAD>
Приведенный тег задает кодировку UTF-8, в которой мы сохранили нашу Web-страничку. Существуют аналогичные теги, задающие кодировки 1251, КОИ-8, кодировка западноевропейских и восточноазиатских языков и др.
Кодировка UTF-8 - это разновидность кодировки Unicode, предназначенная для Web-дизайна. Кодировка Unicode (а значит, и UTF-8) может закодировать все символы всех языков, имеющихся на Земле. Именно она в настоящее время чаще всего применяется для создания Web-страниц.
У метатега <META> нет ни содержимого, ни закрывающей пары! Это так называемый одинарный тег, который имеет только открывающую пару. Такой тег действует в той точке HTML-кода, где он сам находится, и либо задает метаданные, либо помещает в соответствующее место Web-страницы какой-либо элемент, не относящийся к тексту. Впоследствии нам будут часто встречаться одинарные теги.
Теперь осталось рассмотреть последний тег, находящийся в самом начале HTML-кода нашей Web-страницы. Этот тег находится даже вне 'всеобъемлющего' тега <HTML> . Метатег <!DOCTYPE> задает, во-первых, версию языка HTML, на которой написана Web-страница, а во-вторых, разновидность данной версии. Так, существуют мета-теги <!DOCTYPE> , указывающие на HTML 5, 'строгую' и 'переходную' разновидности HTML 4.01 (это предыдущая версия языка HTML, еще действующая на данныймомент) и язык XHTML (ответвление HTML, имеющее несколько другой синтаксис).
Так вот, метатег <!DOCTYPE html> , который мы поставили в начало нашей Web-странички, указывает на HTML 5.
Атрибуты HTML-тегов. Последний важный вопрос, который мы здесь рассмотрим, - атрибуты HTML-тегов. После этого мы пока что закончим с HTML и обратимся к принципам современного Web-дизайна.
Посмотрим на тег <META> , задающий кодировку Web-страницы:
<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=utf-8'>
Здесь мы видим, что между символами < и > , помимо имени тега, присутствуют еще какие-то данные. Это атрибуты тега, задающие его параметры. В частности, два атрибута данного тега <META> указывают, что документ представляет собой Web-страницу, и задают ее кодировку.
Каждый атрибут тега имеет имя, за которым ставится знак равенства, и значение данного атрибута, взятое в двойные кавычки. Так, атрибут с именем HTTP-EQUIV имеет значение 'Content-Type' , говорящее о том, что данный метатег задает тип документа. А атрибут с именем CONTENT имеет значение 'text/html; charset=utf-8' , обозначающее, что данный документ представляет собой Web-страницу, и указывающее, что она набрана в кодировке UTF-8.
Атрибуты тегов бывают обязательными и необязательными. Обязательные атрибуты должны присутствовать в теге в обязательном порядке. Необязательные же атрибуты могут быть опущены; в таком случае тег ведет себя так, будто соответсвующему атрибуту присвоено значение по умолчанию.
Атрибуты HTTP-EQUIV и CONTENT тега <META> обязательные - кому нужен метатег без метаданных... А вот атрибут ID , поддерживаемый практически всеми тегами HTML, необязательный, он используется только в особых случаях:
<H1 ID='header1'>Справочник по HTML</H1>
Ранее мы рассмотрели три правила написания HTML-кода. Добавим к ним еще шесть.
Имена атрибутов тегов могут быть написаны как прописными (большими), так и строчными (малыми) буквами. Традиционно в языке HTML имена атрибутов тегов пишут прописными буквами, а их значения - строчными, если, конечно, значение не чувствительно к регистру букв.
Имена атрибутов тегов пишут между символами < и > после имени тега и отделяют от него пробелом или разрывом строки. Если в теге присутствуют несколько атрибутов, их отделяют друг от друга также пробелами или разрывами строки.
Внутри имен атрибутов не должны присутствовать пробелы, в противном случае Web-обозреватель посчитает, что это не один атрибут, а несколько.
Значение атрибута тега пишут после его имени и заключают в двойные кавычки. Между именем атрибута тега и его значением ставят знак равенства.
Между именем атрибута тега, знаком равенства и открывающими кавычками могут присутствовать пробелы или разрывы строк.
Символы двойных кавычек недопустимы и не должны присутствовать в обычном тексте, иначе Web-обозреватель посчитает следующий за ними текст значением атрибута тега.
Web-обозреватель. Web-обозревателей на свете довольно много. Но если отбросить старые и специализированные, останется всего пять: Microsoft Internet Explorer, Mozilla Firefox, Opera, Google Chrome и Apple Safari.
Разумеется, все эти программы поддерживают языки HTML, CSS (язык описания каскадных таблиц стилей) и JavaScript (язык, на котором пишутся Web-сценарии).
Большинство этих программ поддерживает некоторый набор возможностей HTML 5 и CSS 3 (новая версия CSS):
Mozilla Firefox - начиная с версии 3.5;
Opera - начиная с версии 9.5;
Google Chrome - начиная с версии 2.0.158.0;
Apple Safari - начиная с версии 4.0.
Отдельные возможности HTML 5 и CSS 3 начали поддерживаться и в более ранних версиях этих программ. Однако, чтобы успешно просматривать Web-страницы, следует использовать указанные версии или более новые.
А что же Microsoft Internet Explorer? Поддерживает ли он HTML 5 и CSS 3 на данный момент? К сожалению, нет. Поддержку HTML 5 и CSS 3 обещают лишь в версии 9.0, которая сейчас только разрабатывается.
Но какой же Web-обозреватель нам выбрать? Какой угодно из перечисленных представителей 'передовой четверки' -- Firefox, Opera, Chrome или Safari. А лучше -- сразу все, чтобы удостовериться, что наши Web-страницы в любом из них отображаются правильно.
1.3 Технология CSS
Спецификация языка разметки HTML позволяет разработчику электронных документов изменять внешний вид некоторых элементов страниц. Для этого составляются специальные правила отображения конкретного элемента в HTML-документе, называемые каскадными таблицами стилей (Cascading Style Sheets, CSS) или стилевыми шаблонами [1, 2, 3].
Разберем по составу это понятие - каскадная таблица стилей:
Каскадная.
Спецификация HTML разрешает использовать для одного и того же элемента несколько стилевых правил, интерпретируемых браузером последовательно, другими словами - каскадом;
Таблица.
Формат записи стилевых правил CSS напоминает табличное представление данных. Заголовок таблицы соответствует наименованию элемента, класса или идентификатора стиля. В качестве ячеек и рядов таблицы выступают стилевые свойства и их значения. Судите сами:
DIV
{
font-family: Tahoma;
color: black;
font-size: 12px;
}
стиль. Под стилем принято понимать приведение какого-то явления к общему набору правил и определений. CSS - это способ дополнительного форматирования стандартных тегов HTML. использование внутреннего шаблона и импортирования таблицы стилей и пр. Более подробно о способах определения таблиц стилей будет рассказано в разделе 'Способы определения таблиц стилей'этой главы;
независимость от других языков определения стиля (Independence from specific style sheet languages). Спецификация HTML позволяет, помимо CSS, использовать другие языки определения стилевых шаблонов, что делает создаваемый электронный документ стиленезависимым, а значит и более адаптируемым к изменению внешнего вида определенных HTML-элементов;
каскадность (Cascading). Возможность определения нескольких стилевых правил (указания нескольких таблиц стилей) для одного элемента HTML. He все языки таблиц стилей поддерживают каскадность. Свойство каскадное™ реализуется за счет последовательного чтения стилевых данных браузером;
привязанность к носителю информации (Media dependencies). С помощью стилевых шаблонов CSS возможна ориентация создаваемого электронного документа на различные носители информационных данных: операционные системы Windows и Macintosh, телевизионные и игровые приставки, мобильные телефоны и карманные персональные компьютеры (КПК), устройства распознавания человеческой речи и пр;
П альтернативные стили (Alternate styles).
Разработчики электронных документов могут создавать несколько вариантов отображения элементов HTML с помощью различных таблиц стилей CSS.
Уровни CSS. Впервые каскадные таблицы стилей CSS были реализованы в браузере Internet Explorer 3.0. Однако в то время развитие CSS находилось в зачаточном состоянии, поэтому правила составления стилевых шаблонов были весьма разрозненными. С момента своего возникновения структура CSS была несколько раз пересмотрена, в нее были добавлены новые элементы и убраны (видоизменены) старые. Существуют три уровня CSS, определяемых наличием завершенной редакции структуры. Это: CSS 1 (первый уровень структуры стилевых шаблонов, окончательно утвержденный 11 января 1999 года), CSS 2 (второй уровень стилевых конструкций, начало обсуждения которого датируется маем 1998 года) и CSS 3 (третий уровень стилевого оформления электронных документов, принятый к обсуждению 23 мая 2001 года, на момент написания книги находился в стадии проработки).
В завершение разговора об уровнях CSS следует добавить, что переход от одного уровня к другому, в основном, сопровождался некоторыми видоизменениями в структуре и в правилах стилевого оформления, технологическими дополнениями, а также попытками систематизировать применение CSS.
Создание интерактивных HTML-документов. Именно третий уровень (CSS 3) позиционируется разработчиками в качестве некой единой системы представления стилей в электронном документе, основанной на использовании специальных модулей.
Способы определения таблиц стилей. Как уже было сказано, любая таблица стилей CSS должна быть интерпретирована браузером для того, чтобы правила CSS, обозначенные для конкретных элементов электронного документа, вступили в силу.
Определение таблицы стилей (стилевого шаблона) возможно четырьмя способами:
ссылка на внешний файл. Если все стилевые шаблоны для конкретного HTML-документа разместить в одном текстовом файле (с расширением ess), то с помощью специального тега <LINK> из текущего документа можно сделать ссылку на внешний CSS-файл стилевых шаблонов, например:
<LINK REL='stylesheet' TYPE='text/css' HREF='style.css'>
Браузер, анализируя HTML-код, обратится по указанному пути и, обнаружив указанный файл стилевого оформления, отобразит элементы страницы в соответствии с определенными правилами CSS.
Следует помнить, что конструкция указания пути к внешнему CSS-файлу должна находиться в пределах раздела HEAD HTML-документа;
внедрение в документ. Под внедрением в документ подразумевается задание стилевой конструкции внутри самой HTML-страницы, например:
<STYLE TYPE='text/css'>
< ! --
BODY { font-family: Arial, Helvetica; }
INPUT { background-color: #CECECE; }
-->
</STYLE>
Данная конструкция также должна присутствовать в разделе HEAD. Для браузеров, не поддерживающих CSS вообще или поддерживающих лишь отдельные правила стилевого оформления, описание шаблонов заключается между символами комментариев (при отсутствии поддержки CSS браузер пропустит содержание стилевых шаблонов, если же поддержка есть, то браузер интерпретирует правила CSS);
включение в теговые конструкции.
Любой отдельный HTML-элемент может быть подвергнут форматированию средствами CSS. Для этого необходимо задать определенное правило реализации того или иного тега, например:
<Р ALIGN='justify' STYLE='color: #000000; font-family: Verdana;'>
Текст параграфа...
В этом случае задано отдельное правило для конкретного параграфа. Также можно присваивать отдельному HTML-элементу определенный класс стилевого шаблона:
<TABLE>
<TR>
<TD CLASS='header'x/TD>
<TD CLASS='text'x/TD>
</TR>
</TABLE>
Описание классов должно строиться следующим способом (на примере внедрения стилевого шаблона в документ):
<STYLE TYPE='text/css'>
< ! --
.header { font-weight: bold; color: gray; }
.text { color: black; font-size: llpx; }
-->
</STYLE>
В данном случае текст табличной ячейки класса .header будет отображаться жирным начертанием и серым цветом, а ячейки класса . text -обычным начертанием, черным цветом и размером шрифта 11 пикселов;
импортирование.
Импортирование стилевого шаблона CSS, по сути, аналогично указанию ссылки на внешний файл:
<STYLE TYPE='text/css'>
< i --
Simport: url(style.ess);
-->
</STYLE>
Все четыре способа определения стилевого шаблона CSS можно использовать одновременно в пределах одного HTML-документа. Такая возможность позволяет задавать основное правило CSS, к примеру, в виде внешнего файла шаблонов, а для исключительных или редких HTML-элементов -- отдельные конструкции либо в теге <STYLE>, либо в кодовых конструкциях самих тегов.
<HTML>
<HEAD>
<Т1ТЬЕ>Совмещение различных способов определения CSS</TITLE>
7 Зак. 863
186 _ Часть II. Создание интерактивных HTML -документов
<LINK REL='stylesheet' TYPE='text/css' HREF='style.css'>
<STYLE TYPE='text/css'>
<! --
P { text-align: justify; color: green; }
.title { color: blue; font-weight: bold; font-size: 16px; }
-- >
</STYLE>
</HEAD>
<BODY BGCOLOR='#FFFFFF' TEXT='black' LINK='#OOFFOO' ALINK='#OOFFOO'
VLINK='blue'>
<FONT CLASS='title'>Cnoco6bi определения шаблонов CSS</FONT>
Ниже перечислены существующие способы определения стилевых шаблонов CSS, даны характеристики каждого способа, приведены примеры их использования.
<UL>
<Ы>Ссылка на внешний файл
<и>Внедрение в документ
<Ы>Включение в теговые конструкции
<Ы>Импортирование
</UL>
</BODY>
</HTML>
Также следует сказать, что использование каждого способа определения стилевых шаблонов CSS может быть связано с некоторыми минусами:
В случае ошибки интерпретации HTML-кода браузером, плохой связи с сервером и пр. внешний файл CSS может не загрузиться, вследствие чего стиль для нужных элементов HTML не будет переопределен.
Если внешний файл CSS включает слишком большое количество стилевых шаблонов (что отражается на конечном размере файла), то существует вероятность того, что браузер не сумеет полностью интерпретировать файл CSS или вообще исчерпает лимит времени по загрузке данных. В первом случае стили для части элементов не будут переопределены (браузер успеет 'обнаружить' только те правила, которые размещены в верхней части CSS-файла). Во втором случае все элементы страницы останутся без изменения, загрузившись по умолчанию.
При использовании способа включения стиля в сам документ наличие слишком большого количества шаблонов CSS заметно увеличит конечный размер HTML-страницы, что скажется на времени загрузки документа в браузере.
При сочетании различных способов определения стилевых шаблонов следует учитывать особенности браузеров. К примеру, Netscape 'плохо относится' к использованию символа нижнего подчеркивания ( _ ) в указании классов для элементов HTML (.news_titie, ._about и т. д.). Также ряд браузеров (и Netscape в том числе) не подключает стилевой шаблон класса, присвоенного ячейке таблицы <то>/<тн>: конструкция <то CLASs = 'text'>TeKCT</TD> выведет текст по умолчанию, a <TDXFONT CLASs = 'text'>TeKCT</FONT></TD> отобразит текст заданным стилем. Запись шаблона CSS Группировка и наследование Любое правило таблицы стилей CSS состоит из селектора и определения шаблона. Селектор выступает в роли указателя стилевого правила для определенного HTML-элемента или внутреннего класса (идентификатора). Определение шаблона - это описание стилевых правил для обозначенных элементов HTML. Правила чередуются через точку с запятой и заключаются в фигурные скобки.
НЗ { color: blue; font-family: Tahoma, Verdana, Arial; }
В данном примере селектором является элемент заголовка нз, для шаблона которого следует такое определение: цвет - синий, шрифт - Tahoma, либо Verdana, либо Arial. Как видно из примера, для одного селектора приведено описание, содержащее два правила - по цвету заголовка и наименованию гарнитуры. Это говорит о том, что CSS позволяет группировать несколько стилевых правил для одного селектора в рамках единого описания шаблона.
Сравнив запись вида:
НЗ ( color: blue; }
НЗ { font-family: Tahoma, Verdana, Arial; }
и
НЗ { color: blue; font-family: Tahoma, Verdana, Arial; }
можно сделать вывод о том, что группировка правил по селектору позволяет, во-первых, экономить размер CSS-файла, во-вторых - систематизировать структуру описания шаблона.
Другой особенностью таблиц стилей CSS является свойство наследования стилевых правил для нескольких селекторов одновременно, например:
TD, ТН, Р, DIV { text-align: justify; color: gray: font-size: Юрх; }
Такая запись назначает единый стиль отображения текстовой информации для элементов ячейки таблицы (<то>, <тн>), а также параграфов (<Р>) и блоков (<DIV>), а именно: тип выравнивания - по ширине, цвет - серый, размер шрифта - 10 пикселов.
Селекторы. В качестве селектора CSS могут выступать:
элементы HTML.
Переопределение стиля для конкретного элемента страницы:
BODY { color: orange; }
В этом случае весь текст в пределах раздела BODY будет оранжевым. При добавлении, например, таблицы назначение стилевого шаблона пропадет для текста внутри ячеек;
классы.
Использование классов позволяет переопределять стиль как для конкретного элемента, так и для любого элемента, которому присвоен данный класс. Наименование класса начинается с точки и обычно пишется строчными буквами (допускается использование латинских букв и цифр, но наличие специальных символов, нижних подчеркиваний и прочих нестандартных элементов не рекомендуется).
red { color: red; }
В этом случае любой элемент HTML, позволяющий менять цвет, будет отображаться красным, если ему присвоить класс . red:
<FONT CLASS='red'>TeKCT красным цветом</КОЫТ>
или
<HR CLASS='red'>
Если мы дополним селектор класса наименованием конкретного HTML-элемента, то действие стилевого правила будет распространяться только на данный элемент:
HR.red { color: red; }
При указании классов стилевого шаблона следует внимательно следить за тем, поддерживает ли HTML-элемент присваивамый тип переопределения стиля. Например, запись вида:
HR { text-align: justify; }
будет бессмысленной, т. к. горизонтальный разделитель относится к области структурного форматирования и не может содержать текст, который, согласно стилевому правилу, следует растянуть по ширине;
идентификаторы.
Запись идентификатора начинается с символа # (диез) и заканчивается наименованием:
#black { background-color: black; }
Например, присвоив данный идентификатор тегу то, мы получим ячейку таблицы, залитую черным цветом:
<TD ID='black'>H4eUKa черного цвета</ТО>
Сравнив функции селектора класса и идентификатора, можно задаться вполне закономерным вопросом - чем же отличаются эти селекторы? Действительно, формат определения селектора обоих типов аналогичен по структуре и присвоению HTML-элементам. Однако селектор идентификатора часто применяется для задания уникального имени элементу, который задействован в программном сценарии (скрипте). В отличие от него, селектор класса ограничивается, в основном, применением в стилевых шаблонах.
В заключение необходимо обратить особое внимание на невозможность сочетания селекторов различных типов. Нельзя одновременно переопределить стиль для стандартного элемента HTML и для него же, но по конкретному классу/идентификатору.
Псевдоклассы. Псевдоклассами называют определенные условия форматирования HTML-элемента, в соответствии с которыми браузер подставляет необходимые стилевые правила отображения данных. При этом в исходной структуре электронного документа такие классы не присутствуют, они создаются в процессе интерпретации HTML-кода браузером.
В основном, псевдоклассы предназначены для задания различных типов форматирования по нескольким разновидностям элементов. Рассмотрим функциональность псевдоклассов на примере гиперссылок.
Согласно спецификации HTML и стандарту CSS, гиперссылка может при нимать четыре состояния: непосещенная ссылка (link), посещенная ссылка (visited), активная ссылка (active) и ссылка при наведении курсора мыши (hover). Первые Три СОСТОЯНИЯ (link, visited, active) обычно ПрОПИСЫваются в теге <BODY> HTML-документа (уровень CSS 1). Четвертое состояние (hover) относится к уровню CSS 2 и подразумевает изменение цвета ссылки при наведении на нее курсора мыши пользователя (событие работает в браузерах Internet Explorer 4 и выше, Opera 5 и выше, Netscape 6 и выше, Mozilla 1.0; браузеры более ранних версий, а также некоторые не особенно распространенные браузеры не поддерживают состояние hover).
Эти состояния и будут являться псевдоклассами при записи правил отображения гиперссылок в стилевом шаблоне:
A:link { color: blue; }
A:active { text-decoration: underline; }
A:visited { color: gray; }
A:hover { color: orange; }
В данном случае все присутствующие в электронном документе гиперссылки будут отображаться в соответствии с заданным стилевым правилом.
Однако часто возникает необходимость визуально выделить одни ссылки относительно других. Для этого наряду с псевдоклассами используются обычные селекторы классов:
A:active.red { color: red; }
A:hover.red ( color: blue; }
A:active.white { color: white; }
A:hover.white ( color: black; }
Применение таблиц стилей CSS. Прежде всего следует отметить, что при определении стилевых таблиц далеко не всегда свойства стандартного HTML-элемента соответствуют описанию шаблона стиля. Например, в HTML для жирного начертания используется тег-контейнер <в> (<STRONG>), а в CSS - конструкция font-weight: bold,- (для элемента или селектора). Для выделения текста подчеркиванием в HTML предусмотрен тег <и>, а в CSS используется запись вида text-decoration: underline; И Т. Д.
В рамках данной книги, посвященной применению языка разметки HTML, сложно рассказать обо всех свойствах переопределения стиля с помощью CSS. Поэтому мы остановимся лишь на некоторых аспектах использования каскадных таблиц стилей, а именно: на форматировании текста, структурном форматировании и организации пользовательских форм.
CSS в форматировании текста. CSS предоставляет разработчику электронных документов гораздо более широкий набор возможностей работы с текстовой информацией, нежели стандартный HTML. Помимо способов выделения текста (подчеркивание, курсив, жирное начертание, выбор гарнитуры и размер шрифта), с помощью средств CSS возможно изменять такие параметры, как межбуквенный и межстрочный интервал, тип регистра (строчные и прописные буквы) и многое другое.
1.4 Язык программирования JavaScript
JavaScript это созданный фирмой Netscape межплатформенный, объектно-ориентированный язык скриптинга (сценариев). Ядро JavaScript содержит набор основных объектов, таких как Array, Date и Math, и основной набор элементов языка, таких как операции, структуры управления и операторы [6, 12, 15, 16, 17]. Ядро JavaScript может быть расширено для различных целей путём дополнения новыми объектами; например:
Клиентский JavaScript расширяет ядро языка, предоставляя объекты управления браузером (Navigator или другой web-браузер) и Document Object Model (DOM). Например, клиентские расширения дают приложению возможность размещать элементы в HTML-форме и реагировать на действия пользователя, такие как щелчок мыши, ввод данных в форму и навигация по страницам.
Серверный JavaScript расширяет ядро языка, предоставляя объекты, относящиеся к запуску JavaScript на сервере. Например, серверные расширения дают приложению возможность соединяться с реляционной БД, сохранять информацию между вызовами приложения или выполнять работу с файлами на сервере.
JavaScript позволяет создавать приложения, работающие по всей сети Internet. Клиентские приложения работают в браузере, таком как Netscape Navigator, а серверные приложения - на сервере, таком как Netscape Enterprise Server. Используя JavaScript, Вы можете создавать динамические HTML-страницы, обрабатывающие пользовательский ввод и имеющиеся данные, используя специальные объекты, файлы и реляционные БД.
Рис. 1.3 - Компоненты JavaScript
С помощью функциональности JavaScript LiveConnect Вы можете организовать взаимодействие кодов Java и JavaScript. Из JavaScript Вы можете инстанциировать объекты Java и получать доступ к их public-методам и полям. Из Java Вы можете получать доступ к объектам, свойствам и методам JavaScript.
Корпорация Netscape изобрела JavaScript, и JavaScript был впервые использован в браузерах Netscape.
Ядро, Клиентский и Серверный JavaScript. Компоненты JavaScript показаны на рисунке 1.3.
Ядро JavaScript. Клиентский и серверный JavaScript имеют следующие общие элементы:
Ключевые слова
Синтаксис операторов и грамматику
Правила написания выражений, переменных и литералов
Лежащую в основе объектную модель (хотя клиентский и серверный JavaScript имеют разные предопределённые объекты)
Предопределённые объекты и функции, такие как Array, Date и Math
Клиентский JavaScript. Web-браузеры, такие как Navigator (2.0 и более поздние версии) могут интерпретировать операторы клиентского JavaScript, внедрённые в HTML-страницу. Когда браузер (или клиент) запрашивает такую страницу, сервер высылает клиенту по сети полное содержимое документа, включая HTML и операторы JavaScript.
Рис. 1.4 - Выполнение операторов клиентского JavaScript
Браузер читает страницу сверху вниз, отображая результат работы HTML и выполняя операторы JavaScript по мере их обнаружения. Этот процесс, проиллюстрированный на рисунке 1.4, производит результат, который видит пользователь.
Операторы клиентского JavaScript, встроенного в HTML-страницу, могут реагировать на пользовательские события, такие как щелчок мыши, ввод данных в форму и навигация по страницам. Например, Вы можете написать функцию JavaScript для проверки ввода пользователем правильной информации в форму, запрашивающую телефонный номер или zip-код. Без передачи по сети внедрённый JavaScript на HTML-странице может проверить введённые данные и вывести диалоговое окно, если пользователь ввёл неверные данные.
Разные версии JavaScript работают со специфическими версиями Navigator'а. Например, JavaScript 1.2 работает с Navigator 4.0. Некоторые возможности JavaScript 1.2 недоступны в JavaScript 1.1 и поэтому недоступны в Navigator 3.0.
Серверный JavaScript. На сервере Вы также можете внедрять JavaScript в HTML-страницы. Серверные операторы могут соединяться с реляционными БД разных производителей, разделять информацию между пользователями приложения, получать доступ к файловой системе сервера или взаимодействовать с другими приложениями через LiveConnect и Java. HTML-страницы с серверным JavaScript могут содержать также клиентский JavaScript.
Рис. 1.5 - Серверный JavaScript в процессе разработки
В отличие от страниц с чисто клиентским JavaScript, HTML-страницы, использующие серверный JavaScript, компилируются в байт-кодовые исполняемые файлы. Эти исполняемые приложения запускаются на выполнение web-сервером, имеющим машину времени выполнения JavaScript. Исходя из этого, создание приложений JavaScript это процесс из двух этапов.
На первом этапе, показанном на рисунке 1.5, Вы создаёте HTML-страницы (которые могут содержать операторы как клиентского, так и серверного JavaScript) и файлы JavaScript. Затем Вы компилируете все эти файлы в единый исполняемый блок.
На втором этапе, показанном на рисунке 1.6, страница приложения запрашивается клиентским браузером. Машина выполнения использует исполняемый блок для просмотра исходной страницы и динамической генерации HTML-страницы, возвращаемой клиенту. Она выполняет все найденные на странице операторы серверного JavaScript. Выполнение этих операторов может добавить новые операторы HTML или операторы клиентского JavaScript в HTML-страницу. Машина выполнения отсылает затем окончательный вариант страницы по сети Navigator-клиенту, который выполняет клиентский JavaScript и отображает результат.
Рис. 1.6 - Серверный JavaScript в процессе выполнения
В отличие от стандартных программ Common Gateway Interface (CGI), все исходники JavaScript интегрированы непосредственно в HTML-страницы, ускоряя разработку и облегчая обслуживание. Служба Session Management Service серверного JavaScript содержит объекты, которые Вы можете использовать для работы с данными, существующими между клиентскими запросами, у нескольких клиентов или нескольких приложений. Служба LiveWire Database Service серверного JavaScript предоставляет объекты для доступа к БД, служащие интерфейсом для серверов Structured Query Language (SQL).
JavaScript и Java. JavaScript и Java напоминают друг друга, но имеют и фундаментальные отличия. JavaScript не имеет статической типизации и строгой проверки типов Java. JavaScript поддерживает большую часть синтаксиса выражений Java и базовые конструкции управления потоком.
В отличие от системы времени компиляции Java, построенной на объявлениях, JavaScript поддерживает систему времени выполнения, основанную на небольшом количестве типов данных: числовых, Булевых и строковых. JavaScript имеет объектную модель на базе прототипов вместо более общей объектной модели на базе классов. Модель на базе прототипов предоставляет возможность динамического наследования; то есть, то, что наследуется, может отличаться для разных объектов. JavaScript также поддерживает функции без специальных требований объявления. Функции могут быть свойствами объектов, исполняемыми как нетипизированные методы.
JavaScript это язык, свободный по форме, по сравнению с Java. Вы не должны объявлять все переменные, классы и методы. Вы не должны учитывать, являются ли методы public, private или protected, и не обязаны реализовывать интерфейсы. Return-типы переменных, параметров и функций не типизированы явно.
Java это язык на базе классов, разработанный для быстрого выполнения и строгой типизации. Строгая типизация означает, к примеру, что Вы не можете привести/cast целое число Java (integer) к ссылке на объект или получить доступ к private-памяти, нарушая байт-коды Java. Модель Java на базе классов означает, что программы состоят исключительно из классов и их методов. Наследование классов в Java и строгая типизация обычно требуют тесно выстроенной иерархий объектов. Эти требования делают программирование на Java более сложным, чем авторизация на JavaScript.
В противоположность этому, JavaScript ведёт своё начало от небольших динамически типизированных языков, таких как HyperTalk и dBASE. Эти языки сценариев предоставляют утилиты программирования для более широкой аудитории, поскольку имеют облегчённый синтаксис, специализированную встроенную функциональность и минимальные требования при создании объектов.
Таблица 1.1 - Отличия языков Java и JavaScript
JavaScript |
Java |
|
Интерпретируется (не компилируется) клиентом. |
Скомпилированные байт-коды, загруженные с сервера, выполняются на клиенте. |
|
Объектно-ориентированный. Нет отличий между типами объектов. Наследование осуществляется через механизм прототипов, а свойства и методы могут добавляться к объекту динамически. |
На базе классов. Объекты делятся на классы и экземпляры, наследующие по всей цепи иерархии классов. Классы и экземпляры не могут иметь свойства и методы, добавляемые динамически. |
|
Коды интегрированы и внедрены в HTML. |
Аплеты отличаются от HTML (доступ к ним осуществляется из HTML-страниц). |
|
Типы переменных не объявляются (динамическая типизация). |
Типы переменных обязаны быть объявлены (статическая типизация). |
|
Не может автоматически записывать на жёсткий диск. |
Не может автоматически записывать на жёсткий диск. |
Отладка в JavaScript. JavaScript позволяет создавать сложные компьютерные программы. Как и во всех других языках, Вы можете ошибаться при написании скриптов. Отладчик Netscape JavaScript Debugger даёт возможность отлаживать Ваши скрипты.
Visual JavaScript. Netscape Visual JavaScript это утилита визуальной разработки на базе компонентов для платформы Netscape Open Network Environment (ONE). Он первоначально предназначался для использования разработчиками межплатформенных стандартизованных web-приложений из готовых компонентов с минимальными затратами на программирование. Эти приложения базируются на HTML, JavaScript и Java.
1.5 Язык программирования PHP
PHP - это скрипт-язык (scripting language), встраиваемый в HTML, который интерпретируется и выполняется на сервере [6, 7, 8, 9, 10, 11, 12].
Основное отличие от CGI-скриптов, написанных на других языках, типа Perl или C - это то, что в CGI-программах вы сами пишете выводимый HTML-код, а, используя PHP - вы встраиваете свою программу в готовую HTML-страницу, используя открывающий и закрывающий теги (в примере <?php и ?>).
PHP является препроцессором HTML. Это значит, что до того, как сервер 'отдаст' файл броузеру, его просматривает препроцессор-интерпретатор. Что это значит? Файлы, которые подвергаются обработке препроцессором, должны иметь определенное расширение (обычно это .phtml или .php3, но эти значения можно поменять) и содержать (хотя это не обязательное требование) код для препроцессора
Отличие PHP от JavaScript, состоит в том, что PHP-скрипт выполняется на сервере, а клиенту передается результат работы, тогда как в JavaScript-код полностью передается на клиентскую машину и только там выполняется.
Любители Internet Information Server найдут, что PHP очень похож на Active Server Pages (ASP), а энтузиасты Java скажут, что PHP похож на Java Server Pages (JSP). Еще некоторыми аналогами PHP являются языки ColdFusion (www.allaire.com) и embperl. Все эти языки позволяют размещать код, выполняемый на Web-сервере, внутри HTML-страниц. Перед отправкой страницы PHP-код проигрывается на сервере и брозеру выдается результат в виде опять таки HTML-страницы, которая может сильно отличаться от той, что хранится на сервере.
Проще всего это показать на примере:
<html>
<head>
<title>Пример</title>
</head>
<body>
<?php echo 'Привет, я PHP-программа!'; ?>
</body>
</html>
После выполнения этого скрипта мы получим страничку, в которой будет написано
Привет, я PHP-программа!
Открыв исходный текст данной страницы мы увидим следующее.
<html>
<head>
<title>Example</title>
</head>
<body>
Привет, я PHP-программа!
</body>
</html>
Как видите, в результирующей странице нет и следа PHP-кода. Весьма просто и бесполезно, но PHP позволяет делать и более сложные и фантастические вещи.
Возможности PHP. В нескольких словах - на PHP можно сделать все, что можно сделать с помощью CGI-программ. Например: обрабатывать данные из форм, генерировать динамические страницы, получать и посылать куки (cookies).
Кроме этого в PHP включена поддержка многих баз данных (databases), что делает написание Web-приложений с использованием БД до невозможности простым.
Неполный перечень поддерживаемых БД приведен в таблице1.2:
Таблица 1.2 - Базы данных, поддерживаемые PHP
Adabas D |
InterBase |
Solid |
|
dBase |
mSQL |
Sybase |
|
Empress |
MySQL |
Velocis |
|
FilePro |
Oracle |
Unix dbm |
|
Informix |
PostgreSQL |
ODBC |
Вдобавок ко всему PHP понимает протоколы IMAP, SNMP, NNTP, POP3 и даже HTTP, а также имеет возможность работать с сокетами (sockets) и общаться по другим протоколам.
Краткая история PHP. Началом PHP можно считать осень 1994 года, когда Rasmus Lerdorf решил расширить возможности своей Home-page и написать небольшой движок для выполнения простейших задач. Такой движок был готов к началу 1995 года и назывался Personal Home Page Tools (отсюда и сокращение PHP). Умел он не очень много - понимал простейший язык и всего несколько макросов.
К середине 1995 года появилась вторая версия, которая называлась PHP/FI Version 2. Приставка FI - присоединилась из другого пакета Rasmusa, который умел обрабатывать формы (Form Interpritator). PHP/FI компилировался внутрь Apache и использовал стандартный API Apache. PHP скрипты оказались быстрее аналогичных CGI - скриптов, так как серверу не было необходимости порождать новый процесс. Язык PHP по возможностям приблизился к Perl, самому популярному языку для написания CGI-программ. Была добавлена поддержка множества известных баз данных (например, MySQL и Oracle). Интерфейс к GD - библиотеке, позволял генерировать картинки на лету. С этого момента началось широкое распространение PHP/FI.
В конце 1997 Zeev Suraski и Andi Gutmans решили переписать внутренний движок, с целью исправить ошибки интерпретатора и повысить скорость выполнения скриптов. Через полгода, 6 июня 1998 года вышла новая версия, которая была названа PHP 3.
К лету 1999 года PHP 3 был включен в несколько коммерческих продуктов. По данным NetCraft на ноябрь 1999 PHP использовался в более чем 1 млн. доменах.
На сегодняшний день (декабрь 1999) готовится к выпуску новая версия PHP 4, в которой внутренний движок будет снова переписан (он имеет название Zend - www.zend.com). Предполагается, что производительность новой версии будет в десятки раз выше, чем у существующей.
Достоинства PHP. Разработчикам Web-приложений нет необходимости говорить, что web-страницы - это не только текст и картинки. Достойный внимания сайт должен поддерживать некоторый уровень интерактивности с пользователем: поиск информации, продажа продуктов, конференции и т.п. Традиционно все это реализовалось CGI-скриптами, написанными на Perl. Но CGI-скрипты очень плохо масштабируемы. Каждый новый вызов CGI, требует от ядра порождения нового процесса, а это занимает процессорное время и тратит оперативную память. PHP предлагает другой вариант - он работает как часть Web-сервера, и этим самым похож на ASP от Microsoft или ColdFusion от Allaire.
Синтаксис PHP очень похож на синтаксис C или Perl. Люди, знакомые с программированием, очень быстро смогут начать писать программы на PHP. В этом языке нет строгой типизации данных и нет необходимости в действиях по выделению/освобождению памяти.
Программы, написанные на PHP, читаются достаточно легко. В отличие от Perl-программ PHP-код легко зрительно прочитать и понять.
В дополнение к своей бесплатности (хотя MySQL требует приобретения лицензии при использовании ее в коммерческих целях) связка PHP-MySQL является кросс-платформенной. Это значит, что вы можете, работая в Windows, разрабатывать приложения под Unix. Кроме того, PHP может работать как внешний CGI-процесс, либо как обычный интерпретатор скриптов, либо как модуль, подключаемый к Apache.
И наконец, так как данный продукт разрабатывается совместными усилиями, существует огромное количество документации и списков рассылки, к которым можно обратиться в случае возникновения каких-либо вопросов. Найденные ошибки исправляются достаточно быстро, ваши предложения и замечания всегда выслушают, рассмотрят, и если они окажутся ценными - реализуют в новой версии.
Недостатки PHP. Рассмотрим недостатки PHP:
Основным недостатком PHP 3, есть то, что по свой идеологии PHP изначально был ориентирован на написании небольших скриптов. Несмотря на то, что движок несколько раз переписывался, PHP 3 не пригоден для использования в сложных проектах - при обработке больших скриптов производительность системы резко падает (предчувствуя возмущение сторонников PHP 3, я скажу, что наличие такого недостатка подтверждает и сам разработчик Zeev Suraski). Однако этот недостаток будет ликвидирован в движке PHP 4, который, по словам того же разработчика, предназначен для работы в больших проектах.
PHP является интерпретируемым языком, и, вследствие этого, не может сравниться по скорости с компилируемым С. Однако при написании небольших программ, что, в общем-то, присуще проектам на PHP, когда весь проект состоит из многих небольших страниц с кодом, вступают в силу накладные расходы на загрузку в память и вызов CGI-программы, написанной на С.
Не такая большая база готовых модулей, как, например, СPAN у Perl. С этим ничего нельзя поделать - это дело времени. В PHP 4 разработчики предусмотрели специальный архив, аналогичный CPAN, и я думаю, очень скоро будет написано достаточное количество модулей для его наполнения.
Нет поддержки сессий (session), как, например, в ASP. В PHP 4 этот недостаток будет устранен.
1.6 Основы MySQL
MySQL - небольшой, компактный многопоточный сервер баз данных. MySQL характеризуется большой скоростью, устойчивостью и легкостью в использовании [13, 14].
MySQL был разработан компанией TcX для внутренних нужд, которые заключались в быстрой обработке очень больших баз данных. Компания утверждает, что использует MySQL с 1996 года на сервере с более чем 40 БД, которые содержат 10,000 таблиц, из которых более чем 500 имеют более 7 миллионов строк.
MySQL является идеальным решением для малых и средних приложений. Исходные тексты сервера компилируются на множестве платформ. Наиболее полно возможности сервера проявляются на Unix-серверах, где есть поддержка многопоточности, что дает значительный прирост производительности. В варианте под Windows, MySQL может запускаться как сервис Windows NT или как обычный процесс на Windows 95/98.
На текущий момент MySQL все еще в стадии разработки, хотя версии 3.22 полностью работоспособны.
MySQL-сервер является бесплатным для некоммерческого использования. Иначе необходимо приобретение лицензии, стоимость которой составляет 190 EUR.
Возможности MySQL. MySQL поддерживает язык запросов SQL в стандарте ANSI 92, и кроме этого имеет множество расширений к этому стандарту, которых нет ни в одной другой СУБД.
Краткий перечень возможностей MySQL.
Поддерживается неограниченное количество пользователей, одновременно работающих с базой данных.
Количество строк в таблицах может достигать 50 млн.
Быстрое выполнение команд. Возможно MySQL самый быстрый сервер из существующих.
Простая и эффективная система безопасности.
MySQL действительно очень быстрый сервер, но для достижения этого разработчикам пришлось пожертвовать некоторыми требованиями к реляционным СУБД. В MySQL отсутствуют:
Поддержка вложенных запросов, типа SELECT * FROM table1 WHERE id IN (SELECT id FROM table2). Утверждается, что такая возможность будет в версии 3.23.
Не реализована поддержка транзакций. Взамен предлагается использовать LOCK/UNLOCK TABLE.
Нет поддержки внешних (foreign) ключей.
Нет поддержки триггеров и хранимых процедур.
Нет поддержки представлений (VIEW). В версии 3.23 планируется возможность создавать представления.
По словам создателей именно пункты 2-4 дали возможность достичь высокого быстродействия. Их реализация существенно снижает скорость сервера. Эти возможности не являются критичными при создании Web-приложений, что в сочетании с высоким быстродействием и малой ценой позволило серверу приобрести большую популярность.
Использование PHP. Создайте текстовый файл под именем test.php3 и напишите в нем следующее:
<html>
<body>
<?php
$myvar = 'Hello World';
echo $myvar;
?>
</body>
</html>
Теперь откройте браузер и наберите в нем UL созданной страницы, например: http://stage/test.php3. На экране в браузере вы должны увидеть следующее:
Hello World
Открыв исходный текст страницы вы увидите в ней следующее:
<html>
<body>
Hello World
</body>
</html>
Это произошло потому, что PHP-движок на сервере просмотрел страницу, нашел в ней PHP-код, обработал его и выдал результат, который Web-сервером был отправлен в ваш браузер.
Это уже не статическая HTML-страница с фиксированным текстом. Это уже настоящая программа, которая может в зависимости от поданных в нее данных может выдавать различные результаты. А эта возможность целиком меняет всю философию публикации документов в Интернете, превращая их из статических в динамические, меняющиеся в зависимости от действий пользователя. В нашей первой странице-программе эти возможности конечно не так уж и сильно видны, ведь единственное, что она делает - это выводит текст, который мы быстрее и проще написали бы руками. Тем не менее уже через несколько страниц вы поймете насколько гибкий и мощный инструмент находится у вас в руках. А пока, рассмотрим подробнее нашу первую PHP-страницу.
Первое, на что надо обратить внимание в вышеприведенном коде, это ограничители. Найдите строку, которая начинается с <?php. Для PHP-движка этот код означает начало блока команд, которые надо обработать и выполнить. Заканчивается блок ограничителем ?>. Иными словами символы <?php и ?> выполняют роль скобок. Все, что находится вне них, PHP-движок пропускает и отправляет в Web без всякой обработки, выполняя лишь только то, что находится внутри этих 'скобок'. Мощь PHP заключается в том, что PHP-код можно вставлять в любое - я подчеркиваю - в любое место HTML-страницы. Несколько позже мы рассмотрим некоторые из весьма интересных приемов, а сейчас давайте опустим подробности. Вместо скобок <?php … ?> можно использовать и сокращенную нотацию <? … ?>.
Некоторым программистам, которые работают также с ASP, удобнее писать скобки используя комбинацию <% … %>. PHP можно настроить и на использование таких скобок, если вам лень перестраиваться.
Возможен еще один из вариантов скобок показан ниже:
<SCRIPT LANGUAGE='PHP'>
инструкции
<SCRIPT>
Еще одна деталь, на которую вы обратите внимание, - это точка с запятой в конце каждой строки кода. Это так называемые 'разделители', которые служат для отделения одного набора команд от другого. Вообще-то весь PHP-код можно писать в одной строке, разделяя команды точкой с запятой. Но читать такой код будет неудобно, поэтому в наших примерах после каждой точки с запятой мы ставили перевод строки, а также еще один перевод строки, чтобы яснее выделить группы команд. Не забывайте про точку с запятой в конце строки, это наиболее частая ошибка у начинающих программистов.
Наконец, вы заметили, что перед словом myvar стоит символ $ (доллар). Этот символ сообщает PHP, что перед ним переменная. Мы присвоили (используя символ '=') строку 'Hello World' переменной $myvar. Переменные помимо строк могут содержать числа и массивы. В любом случае любая переменная всегда обозначается символом $.
Истинная сила языка PHP содержится в его функциях. В теории, функция - это блок команд, который выполняет какую-то операцию. Если скомпилировать PHP со всеми имеющимися для него дополнениями, вы получите доступ к более чем 700 функциям. Так что, свои собственные функции вам придется писать разве что в исключительном случае.
Каждая функция имеет свое название и синтаксис. В первом нашем примере была использована функция echo, которая, как вы догадались, выводит строку, заключенную в кавычки, или переменную, которая идет следом.
Давайте еще раз внимательно рассмотрим исходную PHP-страницу. В принципе, она ни чем не отличается от обычной HTML-страницы. Только вместо расширения .html (или .htm) мы ей присвоили расширение .php3. Для Web-сервера это расширение послужило сигналом, что данную страницу перед отправкой надо пропустить через PHP-движок. Строки <html><body> …. </body></html> будут проигнорированы PHP-движком. Он обратит внимание только на то, что написано внутри скобок <?php … ?>. В результате мы получим то, что изображено на рис. 2. В принципе, всю HTML-страницу мы могли бы сгенерировать с помощью PHP-команд, например:
<?php
echo '<html>';
echo '<body>';
$myvar = 'Hello World';
echo $myvar;
echo '</body>';
echo '</html>';
?>
Результат был бы тот же. Но с точки зрения программирования вообще, этот код - не качественный. Ведь PHP-движку придется обработать уже шесть строчек кода вместо прежних двух. Зачем утруждать PHP-движок выводом тегов <html>, <body>, </body>, </html>, если они и так выводятся в странице? При написании кода никогда не забывайте о производительности. Всегда старайтесь улучшить или изменить код так, чтобы у PHP-движка уходило как можно меньше времени на его обработку. Некоторые советы по оптимизации кода мы приведем несколько позднее.
Одной из очень полезных функций языка PHP является phpinfo(). Она выводит на экран всю информацию о PHP-движке, установленном на сервере, причем в форме удобной таблицы. Создайте следующую страницу и вызовите ее из браузера:
<html>
<body>
<?php
phpinfo();
?>
</body>
</html>
В связи с этим примером хочется вспомнить знаменитую фразу из старого фильма: 'Всего одна строка, а как много она нам говорит'. Перед нами страница, наполненная различными интересными и полезными сведениями не только о самом PHP-движке, но и о Web-сервере, его расширениях и возможностях. Найдете строки, начинающиеся на MySQL. Они содержат информацию о MySQL, работающем на сервере. Если эти строки отсутствуют, значит по каким-то причинам PHP не поддерживает работу с MySQL. Обратитесь в первым главам данной книги, а, если потребуется, то и к документации, и проверьте, все ли вы правильно сделали.
Вывод текста в HTML-страницу. Самый простейший способ общения с пользователем через Web-страницу, это послать ему в странице какой-нибудь текст. Это можно сделать двумя способами: с помощью функции print или echo:
<?php
print 'Hello, world.';
?>
<?php
echo 'Hello, world.';
?>
Print это функция, которая отправляет браузеру текст. Между словом 'print' и символом ';' мы помещаем строку, которая обозначается кавычками. Все, что находится внутри кавычек, будет отправлено браузеру. Зная это, мы теперь можем отправить текст 'hello World' несколькими способами. Создайте файл print.php3 со следующим текстом:
<html>
<body>
<?php
print 'Здесь используется функция print.';
print '<p>';
echo 'А здесь использована функция echo.',
' ',
'P.S. Можно добавить вторую текстовую строку.',
' ',
'Текстовые строки разделяются запятыми.';
print '<p>';
printf ('Здесь используется функция printf.');
print '<p>';
printf ('Функция printf в основном используется для форматированного вывода чисел и строк.');
print '<p>';
printf ('Не забывайте о скобках, когда пользуетесь функцией printf.');
?>
</html>
</body>
В результате выполнения кода в браузере мы получим следующий результат:
Здесь используется функция print.
А здесь использована функция echo. Можно добавить вторую текстовую строку. Текстовые строки разделяются запятыми.
Здесь используется функция printf.
Функция printf в основном используется для форматированного вывода чисел и строк. Не забывайте о скобках, когда пользуетесь функцией printf. Функция print - самый простейший способ отправки текста в браузер.
Функция echo работает так же, как и print, однако позволяет добавлять к первой текстовой строке, другие строки, разделяя их запятыми.
Функция printf отображает числа в определенном формате, например, выводит дробное число с определенным количеством нулей после запятой, поэтому в функции printf использование скобок обязательно.
При работе со скобками пользуйтесь следующими тремя правилами:
echo со никогда не используется со скобками
printf всегда используется со скобками
print используется и так и так
Работа с формами. В этом примере показано, как в PHP легко обрабатывать данные, полученные от HTML-форм. Для понимания этой главы от вас требуются крепкие знания языка HTML и принципа работы HTML-форм и а также понимания разницы двух методов передачи данных в них (GET И POST).
Чаще всего серверные скрипты используются для обработки результатов заполнения форм. Например, в гостевой книге посетитель вводит данные в форму, которая затем обрабатывается на сервере. Отвечая на какой-либо опрос пользователь, аналогично, устанавливает значение определенных полей формы.
Напомню, какие теги и атрибуты должна содержать форма:
<FORM NAME='имя_формы'
ACTION='путь_к_обработчику'
METHOD='метод_передачи_переменных'>
поля ввода...
</FORM>
Цветом выделены те элементы, которые пригодятся нам в этом опыте. Прежде всего разберемся, что такое 'обработчик'. Это скрипт на сервере, в который будут переданы значения полей ввода.
Каждое поле ввода имеет атрибут NAME, которое будет передано в обработчик вместе со своим значением. Существует два метода передачи данных: GET и POST. Их отличие состоит в том, что при использовании метода GET значения полей присоединяются к URL, указанному в атрибуте ACTION. Происходит это таким образом:
http://site.domain/action.php3?имя=значение&...имя=значение
Пары 'имя=значение' создаются для каждого элемента ввода, для которого указано имя атрибутом NAME.
В случае использования метода POST значения полей передаются в заголовке запроса к серверу. Формат передачи при этом методе нам, в общем-то, не интересен. Просто примем к сведению, что значения передаются 'незаметно' для обычного пользователя.
При исполнении скрипта на языке PHP создаются переменные с именами, соответствующими именам полей и содержащие соответствующие значения.
Предположим, что мы создали форму следующего вида:
<FORM ACTION='mult.php3' METHOD='GET'>
<INPUT TYPE='text' NAME='first' SIZE='4' MAXLENGTH='4'>
<INPUT TYPE='text' NAME='second' SIZE='4' MAXLENGTH='4'>
<INPUT TYPE='Submit' VALUE='Умножить'>
</FORM>
Скрипт, содержащийся в файле mult.php3 может выглядеть следующим образом:
<?php
Header('Content-type: text/html');
echo '$first умножить на $second получится ', $first*$second;
?>
Необходимо напомнить, что существует специальный тип поля HIDDEN. Это поле, которое не выводится на экран, но, если ему присвоено имя атрибутом NAME, значение его передается в форму. Это бывает полезно, например, когда один обработчик может производить не одно, а несколько действий. С помощью такого поля мы можем задать тип действия, которое мы хотим произвести с данными формы.
Далее перечислены все возможные элементы ввода, которые используются в формах.
TEXT
Поле ввода текста
SELECT
Выбор из списка.
RADIO
Радио-кнопка. Используется для выбора одного из предложенных вариантов.
CHECKBOX
Кнопка-флажок. Используется для выбора варианта.
SUBMIT
Кнопка, которая инициирует вызов обработчика формы.
IMAGE
Изображение. Используется как кнопка типа SUBMIT
<TEXTAREA>
Область ввода текста.
Теперь рассмотрим как значения и состояния этих элементов передаются в обработчик.
TEXT - здесь все просто. Введенное значение передается в виде: имя=значение (для удобства будем предполагать, что метод передачи значений установлен в GET). В обработчике значение можно получить из переменной $имя.
SELECT - значение берется из атрибута VALUE выбранного элемента <OPTION>. Например для <SELECT> такого вида:
<SELECT NAME='mySelect'>
<OPTION VALUE='test1'>test1</OPTION>
<OPTION VALUE='test2'>test2</OPTION>
<OPTION VALUE='test3'>test3</OPTION>
</SELECT>
Cтрока будет содержать mySelect=test1, в случае выбора первого элемента списка. Переменная в скрипте будет выглядеть так: $mySelect.
Элемент <SELECT> может иметь атрибут MULTIPLE, что позволяет выбирать несколько значений из списка. В этом случае к имени элемента <SELECT> необходимо добавить пару квадратных скобок: имя[]. Строка будет выглядеть так: имя[]=значение&имя[]=значение..., а в скрипте доступ к выбранным значениям можно осуществить, как к элементам массива $имя.
В случае, если не заданы атрибуты VALUE, то передаваться будет то, что содержится между тэгами <OPTION> и </OPTION>.
RADIO - Здесь значение будет браться из атрибута VALUE, строка выглядит аналогично элементу типа TEXT. Доступ из скрипта, тоже аналогичен. Если вы забыли установить это значение, то будет передано значение on
CHECKBOX - если флажок установлен, то передается значение on, если флажок не установлен, то переменная не передается вообще. Таким образом, установку флажка в скрипте можно проверить, сравнив значение переменной $имя с 'on'. Переменная и строка выглядят аналогично элементу типа TEXT.
SUBMIT - кнопка SUBMIT, как ни странно, тоже может передавать значение в обработчик. Я не могу себе представить зачем это нужно, но тем не менее. Значение устанавливается из атрибута VALUE. Все остальное аналогично полю типа TEXT.
IMAGE - Самый интересный элемент. В обработчик передаются два значения: имя.x и имя.y, которые представляют собой координату указателя мыши относительно верхнего левого угла изображения. Строка выглядит следующим образом: имя.x=значение&имя.y=значение. В скрипте устанавливаются переменные $имя_x и $имя_y.
<TEXTAREA> - абсолютно аналогично элементу типа TEXT.
При пересылки строковых значений они перекодируются специальным образом. Все символы, кроме алфавитно-цифровых и знака подчеркивания '_' заменяются знаком процента '%' и двумя шестнадцатеричными цифрами кода. Пробелы заменяются на знак '+'. При установке переменных в скрипте производится обратное декодирование.
Еще одну интересную особенность предоставляет PHP. Мы можем каждому элементу присвоить имя переменной массива. Например:
<FORM NAME='testForm' ACTION='test.php3'>
name: <INPUT TYPE='text' NAME='personal[name]'><BR>
e-mail: <INPUT TYPE='text' NAME='personal[email]'><BR>
<INPUT TYPE='SUBMIT'>
</FORM>
В этом случае мы сможем получить доступ к значениям, обращаясь к элементам ассоциативного массива: $personal['name'] и $personal['email'].
Кроме того, если включена директива PHP <?php_track_vars?>, то, при передаче значений, будут заполнены массивы $HTTP_GET_VARS и $HTTP_POST_VARS, для соответствующих методов передачи переменных в обработчик.
Работа с MySQL (вывод данных из базы данных). Для понимания этой главы от вас требуются крепкие знания языка SQL и принципов работы баз данных. Для начала создаем базу данных и таблицу. Входим в командную строку MySQL, и выполняем команды:
mysql > CREATE DATABASE mydb;
mysql> CREATE TABLE employees
( id tinyint(4) DEFAULT '0' NOT NULL AUTO_INCREMENT,
first varchar(20), last varchar(20), address varchar(255),
position varchar(50), PRIMARY KEY (id), UNIQUE id (id));
INSERT INTO employees VALUES
(1,'Bob','Smith','128 Here St, Cityname','Marketing Manager');
INSERT INTO employees VALUES
(2,'John','Roberts','45 There St ,Townville','Telephonist');
INSERT INTO employees VALUES
(3,'Brad','Johnson','1/34 Nowhere Blvd, Snowston','Doorman');
В результате у нас будет создана база данных mydb. В ней будет создана таблица employees (работники). И в эту таблицу будут вставлены три записи с данными о работниках. Для экспериментов с PHP и MySQL этого вполне достаточно.
Давайте выведем эти данные из базы данных в HTML-страницу. Для общения с MySQL из PHP понадобятся следующие функции.
int mysql_connect(string hostname, string username, string password);
Создать соединение с MySQL.
Параметры:
Hostname - имя хоста, на котором находится база данных.
Username - имя пользователя.
Password - пароль пользователя.
Функция возвращает параметр типа int, который больше 0, если соединение прошло успешно, и равен 0 в противном случае.
int mysql_select_db(string database_name, int link_identifier);
Выбрать базу данных для работы.
Параметры:
Database_name - имя базы данных.
link_identifier - ID соединения, которое получено в функции mysql_connect. (параметр необязательный, если он не указывается, то используется ID от последнего вызова mysql_connect)
Функция возвращает значение true или false
int mysql_query(string query, int link_identifier);
Функция выполняет запрос к базе данных.
Параметры:
query - строка, содержащая запрос
link_identifier - см. предыдущую функцию.
Функция возвращает ID результата или 0, если произошла ошибка.
int mysql_result(int result, int i, column);
Функция возвращает значение поля в столбце column и в строке i.
int mysql_close(int link_identifier);
Функция закрывает соединение с MySQL.
Параметры:
link_identifier - см. выше.
Функция возвращает значение true или false
Создайте файл с расширением .php3 и наберите внем следующий текст:
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
$result = mysql_query('SELECT * FROM employees',$db);
printf('First Name: %s<br>n', mysql_result($result,0,'first'));
printf('Last Name: %s<br>n', mysql_result($result,0,'last'));
printf('Address: %s<br>n', mysql_result($result,0,'address'));
printf('Position: %s<br>n', mysql_result($result,0,'position'));
mysql_close($db);
?>
</body>
</html>
Теперь рассмотрим построчно, что происходит в этой программе. Функция mysql_connect() открывает связь с сервером баз данных MySQL. В качестве параметров мы указываем ей имя узла (localhost), на котором находится база данных, имя пользователя (root), под которым мы будем с ней работать, и пароль (в данном случае он пустой и потому не указывается).
Имя узла localhost означает, что сервер MySQL находится на той же машине, что и сам Web-сервер с PHP-движком. В принципе ничто не мешает вам (имея права) обратиться к серверу MySQL, который находится на соседней машине или вообще на другом конце земного шара. Такие эксперименты авторы данной книги уже проводили и весьма успешно. О способах построения приложений с использованием нескольких машин мы поговорим немного позже.
В результате выполнения этой функции получаем некое значение, которое присваиваем переменной $db. Эта переменная называется идентификатором соединения (см. выше описание синтаксиса).
Соединившись с сервером выбираем базу данных, с которой будем работать (ведь на одном и том же сервере могут 'крутиться' несколько баз данных). Это делается с помощью функции mysql_select_db(). В качестве параметров мы передаем название нужной нам базы данных и идентификатор соединения, полученный нами при выполнении предыдущей команды.
В результате выполнения функции mysql_select_db() мы получаем значение true или false. Если соединение с базой данных произошло успешно - true, если нет - false. Для того, чтобы наша программа-страница работала более интеллектуально, мы можем при желании проанализировать возвращаемое значение и если оно будет false, вывести хорошее информативное сообщение об ошибке. Как это делается, мы рассмотрим в других, более сложных примерах.
И, наконец, мы обращаемся к базе данных с запросом, написанным на языке SQL. Для этого служит функция mysql_query(). В качестве первого параметра мы передаем текст запроса, а в качестве второго - 'скармливаем' идентификатор, полученный от выполнения функции mysql_connect().
Результаты выполнения функции mysql_query() - записи, удовлетворяющие нашему запросу - помещаем в переменную $result.
И наконец, с помощью функции mysql_result() извлекаем из результатов выполнения нашего запроса (т.е. переменной $result), первый ряд-запись (который имеет порядковый номер 0), и значение определенного поля (по его имени). Перебирая друг за другом записи от 0 до 2, мы выберем все записи, что хранятся в нашей маленькой базе данных.
В данном коде в полной мере используется функция printf(), с которой мы знакомились в предыдущей главе. Для тех, кто когда-либо работал с языком Perl или C, строки с функцией printf покажутся весьма знакомыми. Если говорить коротко, то в каждой приведенной выше строке комбинация символов '%s' обозначает, что вместо нее должна быть поставлена переменная, идущая во второй части выражения printf. Причем эта переменная должна быть переведена в тип 'строковая переменная'. Более подробное описание синтаксиса функции printf() читайте в руководстве по языку.
Далее познакомимся с более интеллектуальными, чем mysql_result(), функциями выборки данных из БД mysql_fetch_row() и mysql_fetch_array(), В дальнейшем мы рекомендуем пользоваться именно ими, как более быстрыми и удобными, чем mysql_result().
Давайте теперь попробуем вывести все записи, хранящиеся в нашей базе данных. Обратимся к базе данных со следующим кодом:
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
$result = mysql_query('SELECT * FROM employees',$db);
echo '<table border=1>n';
echo '<tr><td>Name</td><td>Position</tr>n';
while ($myrow = mysql_fetch_row($result))
{
printf('<tr><td>%s %s</td><td>%s</td></tr>n', $myrow[1], $myrow[2], $myrow[3]);
}
echo '</table>n';
?>
</body>
</html>
Вы вероятно заметили, что в данном коде вы ввели несколько новых функций и конструкций. Наиболее очевидной из них является цикл while(). Цикл говорит, что до тех пор, пока в переменной $result остается запись для выборки, ее необходимо извлечь с помощью функции mysql_fetch_row и присвоить переменной $myrow. А после этого выполнить код, что расположен внутри фигурных скобок '{}'. Приглядитесь к коду внимательнее и разберитесь в этой конструкции.
Для понимания этого кода разберем понятие 'массив'. Выполнение функции mysql_query дает в результате массив, который хранится в переменной $result. Если представить этот массив в виде таблицы, то результат приведен в таблице 1.3.
Таблица 1.3 - Массив $result
0 id |
1 first |
2 last |
3 address |
4 position |
Порядковый номер элемента массива |
||
$result = |
1 |
Bob |
Smith |
128 Here St, Cityname |
Marketing Manager |
0 |
|
2 |
John |
Roberts |
45 There St, Townville |
Telephonist |
1 |
||
3 |
Brad |
Johnson |
1/34 Nowhere Blvd, Snowston |
Doorman |
2 |
Переменная $result является массивом. Причем не простым массивом, а двумерным. В нем содержатся три строки с номерами от 0 до 2. каждая из которых содержит 5 столбцов от 0 до 4. Для того, чтобы вывести на странице все записи, нам надо пройти от 0-й строчки массива до 2-й. Лучше всего это делать в цикле с помощью функции mysql_fetch_row (которая в переводе буквально означает - 'выбрать ряд').
Функции mysql_fetch_row в качестве параметра подается массив $result. Функция выбирает из него строку, которую мы можем записать в переменную $myrow и автоматически переходит на следующую строку. Вызвав снова mysql_fetch_row, мы выберем следующую строку из массива, и так далее до тех пор, пока не достигнем конца массива. В этом случае mysql_fetch_row вернет значение false, которое послужит нам сигналом, что все записи выбраны и можно завершить цикл.
Теперь наша задача как-то вывести в теле цикла полученную запись. Выбранный ряд у нас хранится в переменной $myrow. Она также, как и $result, является массивом, только одномерным. Массив $myrow приведен в таблице 1.4.
Таблица 1.4 - Массив $myrow
0 id |
1 first |
2 last |
3 address |
4 position |
||
$myrow = |
1 |
Bob |
Smith |
128 Here St, Cityname |
Marketing Manager |
Содержимое переменной $myrow при втором прохождении цикла приведено в таблице 1.5:
приложение интернет магазин страница
Таблица 1.5 - Массив $myrow
0 id |
1 first |
2 last |
3 address |
4 position |
Порядковый номер элемента в массиве $results |
||
$myrow = |
2 |
John |
Roberts |
45 There St ,Townville |
Telephonist |
1 |
И наконец, при третьем прохождении цикла результат приведен в таблице 1.6.
Таблица 1.6 - Массив $myrow
0 id |
1 first |
2 last |
3 address |
4 position |
Порядковый номер элемента в массиве $results |
||
$myrow = |
3 |
Brad |
Johnson |
1/34 Nowhere Blvd, Snowston |
Doorman |
2 |
К каждому столбцу в массиве $myrow мы можем обратиться по его порядковому номеру, который заключается в квадратные скобки. Например, в первом цикле, $myrow[1] равно 'Bob', во втором $myrow[4] равно ' Telephonist'.
На первый взгляд процедура извлечения данных весьма сложна, но она вполне логически понятна и объяснима. Главное не забывайте, что элементы массивов нумеруются от 0, а не от 1, так как здесь мы имеем дело с компьютерной, а не человеческой логикой.
Далее, вывод переменных в HTML с помощью функции printf() - дело техники, уже знакомой нам по предыдущему примеру.
Наш код грешит одним недостатком: если в базе данных не будут найдены записи, удовлетворяющие нашему запросу, мы не получим никакого сообщения об этом. Неплохо было бы, чтобы программа выдавала какое-нибудь сообщение. Сделаем ее более дружественной.
Работа с MySQL (вывод данных из базы данных). Рассмотрим следующий код.
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
$result = mysql_query('SELECT * FROM employees',$db);
if ($myrow = mysql_fetch_array($result))
{
echo '<table border=1>n';
echo '<tr><td>Name</td><td>Position</td></tr>n';
do
{
printf('<tr><td>%s %s</td><td>%s</tr>n', $myrow['first'], $myrow['last'], $myrow['address']);
}
while ($myrow = mysql_fetch_array($result));
echo '</table>n';
}
Else
{
echo 'Sorry, no records were found!';}
?>
</body>
</html>
В данном коде мы опять ввели некоторые новые понятия, но они достаточно просты. Во-первых, вместо функции mysql_fetch_row() мы использовали функцию mysql_fetch_array(). Она работает точно так же, как и mysql_fetch_row() за одним замечательным исключением: с помощью этой функции мы можем обращаться к каждому полю массива не по номеру, а по имени. Например, если раньше для получения имени нам приходилось писать $myrow[1] (1 - второй столбец массива), то теперь мы можем писать $myrow['first'] ('first' - название столбца в базе данных и в массиве). Второй вариант естественно гораздо информативнее и удобнее.
Кроме этого, в коде использован цикл do/while и условная конструкция if-else.
Выражение if-else говорит, что если мы можем присвоить значение $myrow, то надо начать выборку, в противном случае мы понимаем, что записей нет, переходим к блоку else и выводим соответствующее сообщение. Чтобы проверить, как работает эта часть кода, замените SQL-выражение на 'SELECT * FROM employees WHERE id=6' или на какое-нибудь другое, которое не даст результата.
Цикл do/while - это всего лишь вариант цикла while(), который мы использовали в предыдущем примере. Мы обратились за помощью к циклу do/while по одной простой причине. В конструкции if мы уже сделали выборку первого ряда и присвоили его переменной $myrow. Если бы мы сейчас воспользовались прежней конструкцией (т.е. while ($myrow = mysql_fetch_row($result)), мы бы затерли значения первой выбранной записи, заменив ее значениями второй записи. В случае же с циклом do/while мы проверяем условие после того, как код цикла выполнится по крайней мере один раз. Таким образом, ни одна запись не ускользнет из наших рук.
А сейчас давайте сделаем код в цикле и if-else конструкцию еще более красивым. Уверен, результат вам понравится.
Сейчас мы поработаем со параметрами запроса. Как вы уже наверняка знаете, существует три способа передачи параметров запроса. Первый, использовать метод GET в форме (с ним мы разобрались в главе 'Работа с формами'). Второй - набрать параметры прямо в адресной строке браузера. И третий, это вставить параметры в обычную ссылку на странице. То есть сделать ссылку примерно такого вида
<a href='http://my_machine/mypage.php3?id=1'>
Сейчас мы научимся создавать такие ссылки на лету.
Для начала, давайте обратимся к базе данных и выведем список персонала. Взгляните на следующий код.
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
$result = mysql_query('SELECT * FROM employees',$db);
if ($myrow = mysql_fetch_array($result))
{
Do
{
printf('<a href='%s?id=%s'>%s %s</a><br>n', $PHP_SELF, $myrow['id'],$myrow['first'], $myrow['last']);
}
while ($myrow = mysql_fetch_array($result));
}
Else
{
echo 'Sorry, no records were found!';
}
?></body>
</html>
Все вам должно быть знакомо, кроме функции printf(). Поэтому, давайте рассмотрим ее поближе. Во-первых, обратите внимание на обратные косые черты. Они говорят PHP-движку, что необходимо вывести символ, следующий за чертой, а не рассматривать его, как служебный символ или как часть кода. В данном случае это касается кавычки, которая нам нужна в тексте ссылки, но для PHP является символом окончания текстовой строки.
Далее, в коде используется интересная переменная $PHP_SELF. В этой переменной всегда хранится имя и URL текущей страницы. В данном случае эта переменная важна для нас потому, что мы хотим через ссылку вызвать страницу из нее самой. То есть вместо того, чтобы делать две страницы, содержащие разные коды для разных действий, мы все действия запихнули в одну страницу. С помощью условий if-else мы будем переводить стрелки с одного кода на другой, гоняя одну и ту же страницу по кругу. Это конечно увеличит размер страницы и время, необходимое на ее обработку, но в некоторых случая, такой трюк очень удобен.
Переменная $PHP_SELF гарантирует нам, что наша страница будет работать даже в том случае, если мы перенесем ее в другой каталог или даже на другую машину.
Как мы уже сказали, ссылки, сгенерированные в цикле ссылаются на ту же самую страницу, только к имени самой страницы на лету добавлена некоторая информация: переменные и их значения. Переменные, которые передаются в строке-ссылке, автоматически создаются PHP-движком, и к ним можно обращаться так, как если бы вы их создавали в коде сами. При втором проходе страницы наша программа отреагирует на эти пары name=value и направит ход исполнения на другие рельсы. В данном случае мы проверим, есть ли переменная $id, и в зависимости от результата выполним тот или иной код. Вот как это будет выглядеть:
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
// display individual record
if ($id)
{
$result = mysql_query('SELECT * FROM employees WHERE id=$id',$db);
$myrow = mysql_fetch_array($result);
printf('First name: %sn<br>', $myrow['first']);
printf('Last name: %sn<br>', $myrow['last']);
printf('Address: %sn<br>', $myrow['address']);
printf('Position: %sn<br>', $myrow['position']);
}
Else
{
// show employee list
$result = mysql_query('SELECT * FROM employees',$db);
if ($myrow = mysql_fetch_array($result))
{
// display list if there are records to display
Do
{
printf('<a href='%s?id=%s'>%s %s</a><br>n', $PHP_SELF, $myrow['id'],
$myrow['first'], $myrow['last']);
}
while ($myrow = mysql_fetch_array($result));
}
else
{
// no records to display
echo 'Sorry, no records were found!';
}
}
?>
</body>
</html>
Код стал уже сложнее, поэтому мы добавили в него некоторые комментарии, чтобы он стал яснее. Для однострочных комментариев можно использовать символы //. Если комментарий нужно уместить на нескольких строчках, используйте скобки /* … */.
Итак, магия закончилась, вы наконец создали действительно полезную PHP-страницу, работающую с MySQL. Теперь давайте научимся добавлять данные с помощью форм.
Работа с MySQL (сохранение данных в базе данных). Мы научились извлекать данные из базы и выводить их на странице. Теперь давай попробуем осуществить обратное действие. С PHP это не составит большого труда. Создадим простую форму:
<html>
<body>
<form method='post' action='<?php echo $PHP_SELF?>'>
First name:<input type='Text' name='first'><br>
Last name:<input type='Text' name='last'><br>
Address:<input type='Text' name='address'><br>
Position:<input type='Text' name='position'><br>
<input type='Submit' name='submit' value='Enter information'>
</form>
</body>
</html>
Обратите внимание, мы опять используем переменную $PHP_SELF. Как мы уже сказали, PHP-код можно как угодно перемешивать с обычным HTML. Также обратите внимание, что название каждого элемента формы совпадает с названием поля в базе данных. Вообще-то, это не обязательно, но весьма удобно, чтобы в дальнейшем не запутаться в том, какая переменная какому полю в базе данных соответствует.
Помимо этого мы присвоили имя кнопке Submit. Это сделано для того, чтобы в коде затем проверить, есть ли переменная $submit. Таким образом, когда страница будет вызываться, мы будем узнавать, вызывается ли она первый или второй раз.
Следует еще раз отметить, что вовсе не обязательно писать код так, чтобы страница снова и снова вызывала саму себя. Программу можно разделить на две, три и более страниц, если угодно. Но при таком подходе, вся программа находится в одном файле, а это бывает весьма удобно.
Итак, давайте добавим код, который будет проверять, введены ли в форму данные. Пока это будет лишь простая проверка, при которой все переменные, передаваемые странице, будут выводиться на экран с помощью переменной $HTTP_POST_VARS. Эта переменная удобна в случае отладки. Если вы хотите вывести на экран вообще все переменные, используемые в странице, вызовите переменную $GLOBALS.
<html>
<body>
<?php
if ($submit) {
// process form
while (list($name, $value) = each($HTTP_POST_VARS)) {
echo '$name = $value<br>n';
}
} else{
// display form
?>
<form method='post' action='<?php echo $PHP_SELF?>'>
First name:<input type='Text' name='first'><br>
Last name:<input type='Text' name='last'><br>
Address:<input type='Text' name='address'><br>
Position:<input type='Text' name='position'><br>
<input type='Submit' name='submit' value='Enter information'>
</form>
<?php
} // end if
?>
</body>
</html>
Ну что ж, выглядит неплохо. Теперь давайте возьмем подданную через форму информацию и внесем ее в базу данных.
<html>
<body>
<?php
if ($submit) {
// process form
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
$sql = 'INSERT INTO employees (first,last,address,position) VALUES ('$first','$last','$address','$position')';
$result = mysql_query($sql);
echo 'Thank you! Information entered.n';
} else{
// display form
?>
<form method='post' action='<?php echo $PHP_SELF?>'>
First name:<input type='Text' name='first'><br>
Last name:<input type='Text' name='last'><br>
Address:<input type='Text' name='address'><br>
Position:<input type='Text' name='position'><br>
<input type='Submit' name='submit' value='Enter information'>
</form>
<?php
} // end if
?>
</body>
</html>
Мы внесли данные в базу. Тем не менее, наш код далек от идеального. Что случится, если при заполнении формы кто-то оставит пустые поля или введет текст в поле, в которое надо ввести число? Что произойдет, если в поданных данных будет ошибка? Не беспокойтесь. Сейчас мы все исправим.
На протяжении всего учебника мы записывали SQL-выражение в переменную ($sql), прежде чем передать запрос в базу данных через функцию mysql_query(). Это делается на случай отладки. Если что-то пойдет не так, мы всегда сможем вывести интересующее нас SQL-выражение на экран и проверить, нет ли в нем ошибок.
Мы уже знаем, как вставлять данные в базу. Теперь давайте научимся менять записи, которые уже находятся в таблице. Редактирование данных сочетает в себе два кода. Которые мы уже проходили: извлечение данных из базы с выводом их на экран, и внесение данных через форму обратно в базу. Тем не менее, программа правки данных немного отличается тем, что мы в форме должны вывести некую конкретную запись. Для начала давайте воспользуемся кодом из предыдущей главы, для вывода списка служащих на экран. Однако теперь информацию о служащих мы будет отображать в форме. Код страницы будет выглядеть так:
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
if ($id) {
// query the DB
$sql = 'SELECT * FROM employees WHERE id=$id';
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
?>
<form method='post' action='<?php echo $PHP_SELF?>'>
<input type=hidden name='id' value='<?php echo $myrow['id'] ?>'>
First name:<input type='Text' name='first' value='<?php echo $myrow['first'] ?>'><br>
Last name:<input type='Text' name='last' value='<?php echo $myrow['last'] ?>'><br>
Address:<input type='Text' name='address' value='<?php echo $myrow['address'] ?>'><br>
Position:<input type='Text' name='position' value='<?php echo $myrow['position'] ?>'><br>
<input type='Submit' name='submit' value='Enter information'>
</form>
<?php
} else {
// display list of employees
$result = mysql_query('SELECT * FROM employees',$db);
while ($myrow = mysql_fetch_array($result))
{
printf('<a href='%s?id=%s'>%s %s</a><br>n', $PHP_SELF, $myrow['id'], $myrow['first'], $myrow['last']);
}
}
?>
</body>
</html>
В этой странице мы просто вывели в каждое поле формы соответствующее значение из базы данных, что было достаточно несложно. Теперь мы усложним программу. Добавим к ней возможность внесения отредактированных данных назад в базу. Опять таки мы прибегаем к помощи кнопки Submit, которой присваиваем имя, чтобы при втором проходе страницы проверить, какую часть кода нам надо выполнять. Также мы здесь используем слегка измененное SQL-выражение.
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
if ($id) {
if ($submit) {
$sql = 'UPDATE employees SET first='$first',last='$last',address='$address',position='$position' WHERE id=$id';
$result = mysql_query($sql);
echo 'Thank you! Information updated.n';
} else {
// query the DB
$sql = 'SELECT * FROM employees WHERE id=$id';
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
?>
<form method='post' action='<?php echo $PHP_SELF?>'>
<input type=hidden name='id' value='<?php echo $myrow['id'] ?>'>
First name:<input type='Text' name='first' value='<?php echo $myrow['first'] ?>'><br>
Last name:<input type='Text' name='last' value='<?php echo $myrow['last'] ?>'><br>
Address:<input type='Text' name='address' value='<?php echo $myrow['address'] ?>'><br>
Position:<input type='Text' name='position' value='<?php echo $myrow['position'] ?>'><br>
<input type='Submit' name='submit' value='Enter information'>
</form>
<?php
}
} else {
// display list of employees
$result = mysql_query('SELECT * FROM employees',$db);
while ($myrow = mysql_fetch_array($result)) {
printf('<a href='%s?id=%s'>%s %s</a><br>n', $PHP_SELF, $myrow['id'], $myrow['first'], $myrow['last']);
}
}
?>
</body>
</html>
Вот так. Нам удалось вместить все, что мы знаем и умеем в один код. Здесь вы можете увидеть, как мы используем выражение if() внутри другого выражения if() для последовательно проверки нескольких условий.
Теперь пришло время свести все вместе и создать одну PHP-страницу.
<html>
<body>
<?php
$db = mysql_connect('localhost', 'root');
mysql_select_db('mydb',$db);
if ($submit) {
// here if no ID then adding else we're editing
if ($id) {
$sql = 'UPDATE employees SET first='$first',last='$last',address='$address',position='$position' WHERE id=$id';
} else {
$sql = 'INSERT INTO employees (first,last,address,position) VALUES ('$first','$last','$address','$position')';
}
// run SQL against the DB
$result = mysql_query($sql);
echo 'Record updated/edited!<p>';
} elseif ($delete) {
// delete a record
$sql = 'DELETE FROM employees WHERE id=$id';
$result = mysql_query($sql);
echo '$sql Record deleted!<p>';
} else {
// this part happens if we don't press submit
if (!$id) {
// print the list if there is not editing
$result = mysql_query('SELECT * FROM employees',$db);
while ($myrow = mysql_fetch_array($result)) {
printf('<a href='%s?id=%s'>%s %s</a> n', $PHP_SELF, $myrow['id'], $myrow['first'], $myrow['last']);
printf('<a href='%s?id=%s&delete=yes'>(DELETE)</a><br>', $PHP_SELF, $myrow['id']);
}
}
?>
<P>
<a href='<?php echo $PHP_SELF?>'>ADD A RECORD</a>
<P>
<form method='post' action='<?php echo $PHP_SELF?>'>
<?php
if ($id){
// editing so select a record
$sql = 'SELECT * FROM employees WHERE id=$id';
$result = mysql_query($sql);
$myrow = mysql_fetch_array($result);
$id = $myrow['id'];
$first = $myrow['first'];
$last = $myrow['last'];
$address = $myrow['address'];
$position = $myrow['position'];
// print the id for editing
?>
<input type=hidden name='id' value='<?php echo $id ?>'>
<?php
}
?>
First name:<input type='Text' name='first' value='<?php echo $first ?>'><br>
Last name:<input type='Text' name='last' value='<?php echo $last ?>'><br>
Address:<input type='Text' name='address' value='<?php echo $address ?>'><br>
Position:<input type='Text' name='position' value='<?php echo $position ?>'><br>
<input type='Submit' name='submit' value='Enter information'>
</form>
<?php
}
?>
</body>
</html>
На первый взгляд код выглядит сложным, однако, это не так. Программа делится на три части. Первое if() выражение проверяет, была ли нажата кнопка Submit, и если была, проводится проверка, есть ли в поданных данных переменная $id. Если ее нет, значит, происходит добавление новой записи. В противном случае мы редактируем уже существующую запись.
Далее мы проверяем, определена ли переменная $delete. Если да, мы удаляем запись. Обратите внимание, что в первом выражении if() мы проверяем переменную, которая была подана с помощью метода POST, а в данном if() выражении мы проверяем переменную, которая является частью данных отправленных с помощью метода GET.
Наконец, мы переходим к действию, которое будет выполняться по умолчанию: то есть выводим просто список служащих и форму. Здесь мы опять проверяем существование переменной $id. Если она существует, мы просим базу данных выдать сведения о выбранном служащем. В противном случае выводим пустую форму.
Все, чему мы научились, мы поместили в один большой код. Мы использовали циклы while() и выражения if(), а также целую гамму основных команд языка SQL - SELECT, INSERT, UPDATE, и DELETE
Наконец, мы рассмотрели, как можно передавать информацию от одной страницы к другой через URL с помощью ссылок и через формы.
1.5 Язык объектного анализа и проектирования UML
Унифицированный Язык Моделирования UML (Unified Modeling Language) представляет собой общецелевой язык визуального моделирования, который разработан для спецификации, визуализации, проектирования и документирования компонентов программного обеспечения, бизнес-процессов и других систем [18, 19, 20, 21]. Язык UML одновременно является простым и мощным средством моделирования, который может быть эффективно использован для построения концептуальных, логических и графических моделей сложных систем самого различного целевого назначения. Этот язык вобрал в себя наилучшие качества методов программной инженерии, которые с успехом использовались на протяжении последних лет при моделировании больших и сложных систем.
Язык UML основан на некотором числе базовых понятий, которые могут быть изучены и применены большинством программистов и разработчиков, знакомых с методами объектно-ориентированного анализа и проектирования. При этом базовые понятия могут комбинироваться и расширяться таким образом, что специалисты объектного моделирования получают возможность самостоятельно разрабатывать модели больших и сложных систем в самых различных областях приложений.
Язык UML предназначен для решения следующих задач:
Предоставить в распоряжение пользователей легко воспринимаемый и выразительный язык визуального моделирования, специально предназначенный для разработки и документирования моделей сложных систем самого различного целевого назначения.
Снабдить исходные понятия языка UML возможностью расширения и специализации для более точного представления моделей систем в конкретной предметной области.
Описание языка UML должно поддерживать такую спецификацию моделей, которая не зависит от конкретных языков программирования и инструментальных средств проектирования программных систем.
Описание языка UML должно включать в себя семантический базис для понимания общих особенностей ООАП.
Поощрять развитие рынка объектных инструментальных средств.
Способствовать распространению объектных технологий и соответствующих понятий ООАП.
Интегрировать в себя новейшие и наилучшие достижения практики ООАП.
С точки зрения визуального моделирования, UML можно охарактеризовать следующим образом. UML предоставляет выразительные средства для создания визуальных моделей, которые единообразно понимаются всеми разработчиками, вовлеченными в проект, и являются средством коммуникации в рамках проекта.
Унифицированный Язык Моделирования (UML):
не зависит от объектно-ориентированных (ОО) языков программирования;
не зависит от используемой методологии разработки проекта;
может поддерживать любой объектно-ориентированный язык программирования.
UML является открытым и обладает средствами расширения базового ядра. На UML можно содержательно описывать классы, объекты и компоненты в различных предметных областях, часто сильно отличающихся друг от друга.
Общая структура языка UML. С самой общей точки зрения описание языка UML состоит из двух взаимодействующих частей, таких как:
Семантика языка UML. Представляет собой некоторую метамодель, которая определяет абстрактный синтаксис и семантику понятий объектного моделирования на языке UML.
Нотация языка UML. Представляет собой графическую нотацию для визуального представления семантики языка UML.
Абстрактный синтаксис и семантика языка UML описываются с использованием некоторого подмножества нотации UML. В дополнение к этому, нотация UML описывает соответствие или отображение графической нотации в базовые понятия семантики. Таким образом, с функциональной точки зрения эти две части дополняют друг друга. При этом семантика языка UML описывается на основе некоторой метамодели, имеющей три отдельных представления: абстрактный синтаксис, правила корректного построения выражений и семантику.
Семантика определяется для двух видов объектных моделей: структурных моделей и моделей поведения. Структурные модели, известные также как статические модели, описывают структуру сущностей или компонентов некоторой системы, включая их классы, интерфейсы, атрибуты и отношения. Модели поведения, называемые иногда динамическими моделями, описывают поведение или функционирование объектов системы, включая их методы, взаимодействие и сотрудничество между ними, а также процесс изменения состояний отдельных компонентов и системы в целом.
Для решения столь широкого диапазона задач моделирования разработана достаточно полная семантика для всех компонентов графической нотации. Требования семантики языка UML конкретизируются при построении отдельных видов диаграмм. Нотация языка UML включает в себя описание отдельных семантических элементов, которые могут применяться при построении диаграмм.
Формальное описание самого языка UML основывается на некоторой общей иерархической структуре модельных представлений, состоящей из четырех уровней:
Мета-метамодель.
Метамодель.
Модель.
Объекты пользователя.
Уровень метаметамодели образует исходную основу для всех метамодельных представлений. Главное предназначение этого уровня состоит в том, чтобы определить язык для спецификации метамодели. Мета-метамодель определяет модель языка UML на самом высоком уровне абстракции и является наиболее компактным ее описанием. С другой стороны, мета-метамодель может специфицировать несколько метамоделей, чем достигается потенциальная гибкость включения дополнительных понятий.
Метамодель является экземпляром или конкретизацией мета-метамодели. Главная задача этого уровня - определить язык для спецификации моделей. Данный уровень является более конструктивным, чем предыдущий, поскольку обладает более развитой семантикой базовых понятий. Все основные понятия языка UML - это понятия уровня метамодели. Примеры таких понятий - класс, атрибут, операция, компонент, ассоциация и многие другие.
Модель в контексте языка UML является экземпляром метамодели в том смысле, что любая конкретная модель системы должна использовать только понятия метамодели, конкретизировав их применительно к данной ситуации. Это уровень для описания информации о конкретной предметной области. Однако если для построения модели используются понятия языка UML, то необходима полная согласованность понятий уровня модели с базовыми понятиями языка UML уровня метамодели.
Конкретизация понятий модели происходит на уровне объектов. В настоящем контексте объект является экземпляром модели, поскольку содержит конкретную информацию относительно того, чему в действительности соответствуют те или иные понятия модели.
Выводы. В данной главе были рассмотрены основы создания современных веб-приложений HTML, PHP, JavaScript и CSS. Все это в совокупности используется для построения интерфейса и бизнес-логики веб-приложения. Для работы с данными используется сервер баз данныз MySQL. Популярным инструмент анализа и проектирования является язык UML.
2. Проектирование веб-приложения «Интернет-аукцион»
2.1 Анализ предметной области
В данном подразделе рассмотрим особенности некоторых аукционов и перейдем к проектирования веб-приложения.
Аукцион. eBay. Аукцион Основной идеей eBay является предоставление продавцам интернет-платформы для продажи любых товаров. Сама фирма eBay выступает лишь в роли посредника при заключении договора купли-продажи между продавцом и покупателем. Оплата товара и его пересылка происходит без участия eBay. За использование платформы продавцы платят взнос, обычно складывающийся из сбора за выставление лота и процента от цены продажи. Для покупателей использование eBay бесплатно.
Так как прибыль eBay напрямую зависит от объёмов продаж, совершённых с помощью этой платформы, на ней действуют достаточно либеральные условия. К продаже разрешены любые товары и услуги, не нарушающие законодательства той страны, в которой зарегистрирован соответствующий филиал eBay и не внесённые в чёрный список eBay.
На рисунке 2.1 показан внешний вид сайта ebay.com.
Рис. 2.1 - Внешний вид сайта ebay.com
Причины эффективности бизнес-модели. Отсутствие географических барьеров -- продавцы и покупатели могут участвовать в торгах на eBay из любой точки мира, достаточно иметь доступ к сети Интернет. Это увеличивает число продавцов/выставляемых лотов и количество покупателей/сделанных ставок.
Отсутствие языковых барьеров -- участие в аукционной торговле возможно на различных языках. Многие страны имеют собственные, локальные филиалы аукциона, например Великобритания, Германия, Нидерланды, Испания, Австралия и этот список может быть продолжен.
Отсутствие временных рамок -- ставки на товары на eBay можно делать 24 часа в сутки, 7 дней в неделю. Лоты, в свою очередь, могут быть выставлены на период до 30 дней -- достаточный период для поиска, ознакомления и покупки.
Большое количество покупателей -- посетители аукционов привлечены огромным ассортиментом разнообразных товаров, выставляемых по относительно низким ценам. Так же здесь можно найти редкие, коллекционные вещи, которые практически невозможно купить оффлайн.
Большое количество продавцов -- низкие затраты на размещение товаров, огромная покупательская аудитория, простота использования сервисов аукциона eBay также привлекательны для продавцов. Более того, продавцом может стать каждый участник.
Мультипликационный эффект модели -- рост количества покупателей приводит к росту числа продавцов, рост числа продавцов стимулирует рост количества покупателей. Что и гарантирует развитие eBay.com во всём мире.
Аукцион ООО «БелАукцион-Групп». Компания, предоставляющая комплексные услуги по организации и проведению аукционных интернет-торгов в сфере реализации транспортных средств и их запчастей на территории Республики Беларусь.
На рисунке 1.2 показан внешний вид сайта ООО «БелАукцион-Групп»
Рис. 2.2 - Главная страница сайта ООО «БелАукцион-Групп»
Развитие бизнеса в направлении:
создающем здоровую и честную потребительскую конкуренцию на рынке транспортных средств Республики Беларусь;
обеспечивающем максимально комфортные и выгодные условия реализации сделок для наших партнёров и клиентов.
Преимущества данного аукциона:
Широкое ассортиментное предложение. Еженедельно выставляются новые Лоты - автомобили, мотоциклы и прочие транспортные средства, аварийные, конфискованные и другие.
Собственная автомобильная площадка «showroom». Все транспортные средства, выставленные на торги, представляются на выставочной базе компании для ознакомления и осмотра.
Развитая служба эвакуации транспортных средств. Компания предоставляет услуги по оперативной эвакуации транспортных средств любого вида.
Бесплатная доставка транспортных средств. Доставка любого транспортного средства от клиента до площадки компании осуществляется бесплатно.
Полный цикл «обслуживания сделки». Клиенты получают полную информационную и консультационную поддержку компании на этапе первого обращения в компанию, а также в процессе осуществления сделки - от момента ее заключения до момента ее окончания.
Профессиональная команда сотрудников. В штате имеются сотрудники с опытом работы в сфере автомобильной аукционной торговли в американских компаниях. Все сотрудники компании получают системное тренинговое обучение и проходят регулярную аттестацию.
Прозрачные сделки. Все совершаемые компанией сделки лежат в правовом поле белорусского законодательства и имеют официальное документальное оформление.
Услуги по приобретению транспортных средств с аукционов США и Европы. Компания предоставляет дополнительные услуги по приобретению и доставке любого транспортного средства, а также запчастей к нему с любого аукциона США и Европы на территорию Республики Беларусь.
Аукцион ООО «БелАвтоЛот». Специализированная организация по проведению торгов (аукционов) по продаже аварийных и целых транспортных средств, а также запчастей и годных остатков транспортных средств.
Преимущества рассматриваемого аукциона:
продажу автомобиля по оптимальным рыночным ценам;
бесплатную эвакуацию транспортного средства по г. Минску к нам на площадку с прохождением процедуры сверки в ГАИ.
исключение случаев обмана и махинаций при продаже авто;
объективность в ходе продажи транспортного средства;
пакет официально заверенных документов о продаже автомобиля, в случаях возникновения спорных ситуаций (для страховых компаний, судебных инстанций или прочих официальных органов).
На рисунке 2.3 показан внешний вид сайта ООО «БелАвтоЛот»
Рис. 2.3 - Внешний вид сайта ООО «БелАвтоЛот»
Аукцион CarOutlet. CarOutlet является одной из ведущих онлайн-платформ в Европе для всех участников рынка подержанных легковых автомобилей и фургонов. Наша цель - сделать процесс продажи простым, безопасным и надежным для покупателей и продавцов. Максимально снизив риски для обеих сторон, мы гарантируем качество и надежность каждого продаваемого на аукционе автомобиля.
Преимущества рассматриваемого аукциона:
более 5000 авто еженедельно;
низкая комиссия;
прозрачное формирование цены;
все сервисные документы, история техобслуживания -- вы сами можете оценить качество авто на основе объективных данных;
качественные фотографии интерьера и экстерьера автомобиля;
доставка до вашего города.
На рисунке 2.4 показан внешний вид сайта caroutlet.eu
Рис. 2.4 - Внешний вид аукциона caroutlet.eu
Аукцион WOLMAR. «Волмар» - лучший аукцион монет в России.
Преимущества аукциона «Волмар»:
Безопасность. За сохранность лота, который выставил нумизмат, аукцион монет несет полную материальную ответственность.
Выгодность. Крупнейшие аукционы монет онлайн предоставляют доступ к сотням тысяч заинтересованных покупателей и продавцов. Участник получает выход на самых материально обеспеченных коллекционеров со всего мира. Посетив такой аукцион нумизматов, продать монеты можно по максимально возможной рыночной стоимости. Аналогичная ситуация с приобретением лотов. Из-за огромного количества выставляемых на онлайн аукционы монет, скупка осуществляется по цене, регулируемой рыночными механизмами, а не пожеланиями конкретного человека.
Удобство. Выставив на нумизматический аукцион монеты, вам больше не нужно никуда ездить или звонить. Ходом торгов вы управляете, сидя в домашнем кресле. Для покупателей также созданы все условия. К каждому лоту прилагается не только основная характеристика конкретной монеты - стоимость, аукционы предоставляют исчерпывающую информацию о ее редкости и сохранности, удобную масштабируемую фотографию, а также подробные сведения о ходе торгов. Словом, здесь есть все необходимое для принятия верного решения.
На рисунке 2.5 показан внешний вид сайта wolmar.ru
Рис. 2.5 - Внешний вид сайта wolmar.ru
2.1 Функциональное моделирование веб-приложения
Для проектирования функциональности веб-приложения задействуем диаграмму Use Case языка UML. Диаграмма Use Case определяет поведение системы с точки зрения пользователя. Диаграмма Use Case рассматривается как главное средство для первичного моделирования динамики системы, используется для выяснения требований к разрабатываемой системе, фиксации этих требований в форме, которая позволит проводить дальнейшую разработку. В русской литературе диаграммы Use Case часто называют диаграммами прецедентов, или диаграммами вариантов использования.
В состав диаграмм Use Case входят элементы Use Case, актеры, а также отношения зависимости, обобщения и ассоциации. Как и другие диаграммы, диаграммы Use Case могут включать примечания и ограничения. Кроме того, диаграммы Use Case могут содержать пакеты, используемые для группировки элементов модели в крупные фрагменты.
Актеры и элементы Use Case. Вершинами в диаграмме Use Case являются актеры и элементы Use Case. Их обозначения показаны на рис. 2.6.
Актеры представляют внешний мир, нуждающийся в работе системы. Элементы Use Case представляют действия, выполняемые системой в интересах актеров.
Рис. 2.6 - Обозначения актера и элемента Use Case
Актер -- это роль объекта вне системы, который прямо взаимодействует с ее частью -- конкретным элементом (элементом Use Case). Различают актеров и пользователей. Пользователь -- это физический объект, который использует систему. Он может играть несколько ролей и поэтому может моделироваться несколькими актерами. Справедливо и обратное -- актером могут быть разные пользователи.
Например, для коммерческого летательного аппарата можно выделить двух актеров: пилота и кассира. Сидоров -- пользователь, который иногда действует как пилот, а иногда -- как кассир. Как изображено на рис. 2.7, в зависимости от роли Сидоров взаимодействует с разными элементами Use Case.
Рис. 2.7 - Модель Use Case
Элемент Use Case -- это описание последовательности действий (или нескольких последовательностей), которые выполняются системой и производят для отдельного актера видимый результат.
Один актер может использовать несколько элементов Use Case, и наоборот, один элемент Use Case может иметь несколько актеров, использующих его. Каждый элемент Use Case задает определенный путь использования системы. Набор всех элементов Use Case определяет полные функциональные возможности системы.
Отношения в диаграммах Use Case. Между актером и элементом Use Case возможен только один вид отношения -- ассоциация, отображающая их взаимодействие (рис. 2.8). Как и любая другая ассоциация, она может быть помечена именем, ролями, мощностью.
Рис. 2.8 - Отношение ассоциации
Между актерами допустимо отношение обобщения (рис. 2.9), означающее, что экземпляр потомка может взаимодействовать с такими же разновидностями экземпляров элементов Use Case, что и экземпляр родителя.
Рис. 2.9 - Отношение обобщения между актерами
Между элементами Use Case определены отношение обобщения и две разновидности отношения зависимости -- включения и расширения.
Отношение обобщения (рис. 2.10) фиксирует, что потомок наследует поведение родителя. Кроме того, потомок может дополнить или переопределить поведение родителя. Элемент Use Case, являющийся потомком, может замещать элемент Use Case, являющийся родителем, в любом месте диаграммы.
Рис. 2.10 - Отношение обобщения между элементами Use Case
Отношение включения (рис. 2.11) между элементами Use Case означает, что базовый элемент Use Case явно включает поведение другого элемента Use Case в точке, которая определена в базе. Включаемый элемент Use Case никогда не используется самостоятельно -- его конкретизация может быть только частью другого, большего элемента Use Case. Отношение включения является примером отношения делегации. При этом в отдельное место (включаемый элемент Use Case) помещается определенный набор обязанностей системы. Далее остальные части системы могут агрегировать в себя эти обязанности (при необходимости).
Рис. 2.11 - Отношение включения между элементами Use Case
Перейдем к построению модели Use Case для веб-приложения аукциона. Выделим следущих актеров - Администратор, Модератор, Редактор, Пользователь. Система имеет проверку роли пользователя при входе, эти права определяют. У Администратора будут максимальные права в системе, включая регистрацию пользователей и работу с категориями и лотами. Модератор имеет возможность работать с категориями и лотами аукциона, в том числе удаление данных сущностей. Редактор может только редактировать и создавать категории и лоты. Пользователь имеет права только создавать лоты и проводить аукцион собственно.
Для всех элементов Use Case и актеров используем связь использования, никакие стереотипы использовать не будем. Будем считать, что все связи имеют направление от актера к элементу Use Case и на модели это приводить не будем. Для построения всех моделей, в том числе и модели Use Case, будем использовать CASE-средство Enterprise Architect. Построенная модель функциональности приведена на рисунке 2.12.
Рис. 2.12 - Модель функциональности веб-приложения
2.3 Поведенческое моделирование веб-приложения
В данном подразделе рассмотрим вопросы моделирования поведения системы интернет-аукциона. Для моделирования системы возьмем язык UML, в котором для моделирования поведения системы используют:
автоматы;
взаимодействия.
Автомат (State machine) описывает поведение в терминах последовательности состояний, через которые проходит объект в течение своей жизни. Взаимодействие (Interaction) описывает поведение в терминах обмена сообщениями между объектами.
Таким образом, автомат задает поведение системы как цельной, единой сущности; моделирует жизненный цикл единого объекта. В силу этого автоматный подход удобно применять для формализации динамики отдельного трудного для понимания блока системы.
Взаимодействия определяют поведение системы в виде коммуникаций между его частями (объектами), представляя систему как сообщество совместно работающих объектов. Именно поэтому взаимодействия считают основным аппаратом для фиксации полной динамики системы.
Автоматы отображают с помощью:
диаграмм схем состояний;
диаграмм деятельности.
Взаимодействия отображают с помощью:
диаграмм сотрудничества (кооперации);
диаграмм последовательности.
В нашем случае для моделирования поведения веб-приложения возьмем диаграмму активности. Практически диаграмма активности представляет собой сценарий выполнения пользователем того или иного действия в системе.
Рис. 2.13 - Сценарий работа в системе Администратора
Возьмем многовариантный сценарий работы в системе Администратора. Центральными атомарными состояниями действия выделим Вход, Создание нового пользователя, Сохранение нового пользователя, Редактирование и Блокировка пользователя. Результат построения модели поведения в Enterprise Architect приведен на рисунке 2.13.
Рассмотрим другие сценарии поведения пльзователей системы. Рассмотрим поведение пользователя с ролью Редактор с случае работы с подсистемой Категории. На рисунке 2.14 приведена построенная диаграмма деятельности в Enterprise Architect. Выделим состояния действия Просмотр категорий, Создание новой категории, Сохранение новой категории и Выход. Все состояния действия соединим между собой потоком управления. В диаграмме использованы элементы UML слияние (merge) и решение (decision).
Рис. 2.14 - Сценарий работы с подсистемой Категории роли Редактора
Перейдем к рассмотрению поведения системы в случае работы пользователя с ролью Пользователь. Он имеет наименьшие права безопасности в данном веб-приложении. Приведем сценарий работы пользователя работы с подсистемой Лоты, построенная в Enterprise Architect диаграмма приведена на рисунке 2.15. В данном случае выделим такие состояния действия (aсtivity), как: Создание лота, Редактирование лота, Просмотр лота, Создание аукциона, Выставление цены на лот аукциона. В данной поведеческой модели для отражения поведения используются элементы слияние (merge) и решение (decision), все элементы UML-модели соединены потоком управления.
В качестве начала диаграммы используется стандартный элемент Начало (Initial) и Окончание (Final). Данные элементы являются стандартными для данного типа диаграмм.
Активность вход в систему является стндартным элементом всех модлей деятельности данного веб-приложения, так как все пользователи проходят процедуру авторизации. Исходя из логина уже в свою очередь определяется роль данного пользователя.
Рис. 2.15 - Сценарий работы с подсистемой Лоты пользователя с ролью Пользователь
2.4 Моделирование базы данных веб-приложения «Интернет-аукцион»
Рассотрим вопрос моделирования базы данных веб-приложения. По распространенной концепции моделирования баз данных выделят логическое и физическое моделирование базы данных. Эти два уровня полностью охватывает подход SADT и реализуется это ER-диаграммами. Ранее стандартом в мире разработки баз данных являлось CASE-средство Erwin. Однако с появлением языка UML моделирования баз данных было встроено во все CASE-средства, использующиеся для разработки промышленных баз данных.
Для данной разработки мы воспользуемся встроенным визуальным дизайнером phpMyAdmin для структурирования базы данных веб-приложения. Фактически это моделирование физической структуры базы данных, впоследствии сгенерируем скрипт базы данных. После определения набора наобходимых таблиц и визуализации структуры посредством визуального дизайнера получен седущий результат, приведенный на рисунке 2.16.
Рис. 2.16 - Структура базы данных
Центральными таблицами базы данных являются таблицы Пользователи, Лоты и Категории. В данном контексте это будут таблицы Users, Lots и Categories. Остальные таблицы являются вспомогательными. Ввиду простоты базы данных не используется механизмы внешних ключей в таблицах, реализация только на уровне программного кода приложения. Во всех таблицах присутствуют уникальные индексы. Типизация полей приведена на рисунке 2.16. На основе данной визуальной структуры мы получаем следующий скрипт базы данных уже на языке SQL.
--SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO';
SET time_zone = '+00:00';
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `auction`
--
-- --------------------------------------------------------
--
-- Table structure for table `categories`
--
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`parent` int(10) unsigned NOT NULL,
`level` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
-- --------------------------------------------------------
--
-- Table structure for table `catextra`
--
CREATE TABLE IF NOT EXISTS `catextra` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`cat` int(10) unsigned NOT NULL,
`name` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Table structure for table `lotextra`
--
CREATE TABLE IF NOT EXISTS `lotextra` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lot` int(10) unsigned NOT NULL,
`catextra` int(10) unsigned NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Table structure for table `lots`
--
CREATE TABLE IF NOT EXISTS `lots` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`organizer` int(10) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`category` int(10) unsigned NOT NULL,
`images` varchar(255) NOT NULL,
`description` text NOT NULL,
`lottype` varchar(40) NOT NULL,
`auctiontype` varchar(40) NOT NULL,
`cost` float NOT NULL,
`step` float NOT NULL,
`startdate` int(16) unsigned NOT NULL,
`enddate` int(16) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
--
-- Table structure for table `messages`
--
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user1` int(10) unsigned NOT NULL,
`user2` int(10) unsigned NOT NULL,
`date` int(16) unsigned NOT NULL,
`lot` int(10) unsigned NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Table structure for table `order`
--
CREATE TABLE IF NOT EXISTS `order` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lot` int(10) unsigned NOT NULL,
`cost` float NOT NULL,
`stages` int(10) unsigned NOT NULL,
`winner` int(10) unsigned NOT NULL,
`completed` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
--
-- Table structure for table `orderstages`
--
CREATE TABLE IF NOT EXISTS `orderstages` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`order` int(10) unsigned NOT NULL,
`cost` float NOT NULL,
`completed` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Table structure for table `panel`
--
CREATE TABLE IF NOT EXISTS `panel` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lot` int(10) unsigned NOT NULL,
`user` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Table structure for table `regions`
--
CREATE TABLE IF NOT EXISTS `regions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`parent` int(10) unsigned NOT NULL,
`level` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`login` varchar(40) NOT NULL,
`password` varchar(40) NOT NULL,
`email` varchar(64) NOT NULL,
`firstname` varchar(64) NOT NULL,
`lastname` varchar(64) NOT NULL,
`patronymic` varchar(64) NOT NULL,
`rights` varchar(40) NOT NULL,
`activated` tinyint(3) unsigned NOT NULL,
`regdate` int(16) unsigned NOT NULL,
`token` varchar(40) NOT NULL,
`blocked` tinyint(3) unsigned NOT NULL,
`blockend` int(16) unsigned NOT NULL,
`reserved` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `login` (`login`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
--
-- Table structure for table `ventures`
--
CREATE TABLE IF NOT EXISTS `ventures` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lot` int(10) unsigned NOT NULL,
`user` int(10) unsigned NOT NULL,
`cost` float NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
--
-- Dumping data for table `ventures`
--
INSERT INTO `ventures` (`id`, `lot`, `user`, `cost`) VALUES
(2, 6, 1, 1100000),
(3, 8, 2, 1200000),
(4, 5, 2, 570000),
(5, 3, 2, 540000);
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Выводы. В разделе 2 дано понятие интернет-аукциона, рассмотрены преимущества интернет-аукциона, универсальный интернет-аукцион eBay, интернет-аукцион целых и аварийных автомобилей, и их запчастей, интернет-аукцион автомобилей, целых частей автомобилей и их запчастей ООО «БелАвтоЛот», интернет-аукцион по продаже подержанных автомобилей и фургонов CarOutlet, интернет-аукцион по продаже монет «Волмар». Также с помощью языка UML построена модель требований к веб-приложению интернет-аукциона, выделен функционал и пользователи системы, построены поведеческие модели системы на языке UML. Также было проведено моделирование базы данных веб-приложения.
3. Разработка клиент-серверного веб-приложения «Интернет-аукцион»
3.1 Диаграмма компонентов
В данном разделе рассмотрим вопросы реализации программной системы «Интернет-аукцион». Для описания реализации системы задействуем диаграммы реализации - компонентную и размещения языка UML. В конце данного раздела приведем интерфейс веб-приложения. Все листинги модулей приведены в приложениях.
Компонентная диаграмма -- первая из двух разновидностей диаграмм реализации, моделирующих физические аспекты объектно-ориентированных систем. Компонентная диаграмма показывает организацию набора компонентов и зависимости между компонентами.
Элементами компонентных диаграмм являются компоненты и интерфейсы, а также отношения зависимости и реализации. Как и другие диаграммы, компонентные диаграммы могут включать примечания и ограничения. Кроме того, компонентные диаграммы могут содержать пакеты или подсистемы, используемые для группировки элементов модели в крупные фрагменты.
Компоненты. По своей сути компонент является физическим фрагментом реализации системы, который заключает в себе программный код (исходный, двоичный, исполняемый), сценарные описания или наборы команд операционной системы (имеются в виду командные файлы). Язык UML дает следующее определение.
Компонент -- физическая и заменяемая часть системы, которая соответствует набору интерфейсов и обеспечивает реализацию этого набора интерфейсов.
Интерфейс -- очень важная часть понятия «компонент», его мы обсудим в следующем подразделе. Графически компонент изображается как прямоугольник с вкладками, обычно включающий имя (рис. 5.1).
Рис. 3.1 - Обозначение компонента
Компонент -- базисный строительный блок физического представления ПО, поэтому интересно сравнить его с базисным строительным блоком логического представления ПО -- классом.
Сходные характеристики компонента и класса:
наличие имени;
реализация набора интерфейсов;
участие в отношениях зависимости;
возможность быть вложенным;
наличие экземпляров (экземпляры компонентов можно использовать только в диаграммах размещения).
Интерфейсы. Интерфейс -- список операций, которые определяют услуги класса или компонента. Образно говоря, интерфейс -- это разъем, который торчит из ящичка компонента. С помощью интерфейсных разъемов компоненты стыкуются друг с другом, объединяясь в систему.
Еще одна аналогия. Интерфейс подобен абстрактному классу, у которого отсутствуют свойства и работающие операции, а есть только абстрактные операции (не имеющие тел). Если хотите, интерфейс похож на улыбку чеширского кота из правдивой истории об Алисе, где кот отдельно и улыбка отдельно. Все операции интерфейса открыты и видимы клиенту (в противном случае они потеряли бы всякий смысл). Итак, операции интерфейса только именуют предлагаемые услуги, не более того.
Очень важна взаимосвязь между компонентом и интерфейсом. Возможны два способа отображения взаимосвязи между компонентом и его интерфейсами. В первом, свернутом способе, как показано на рис. 5.3, интерфейс изображается в форме пиктограммы. Компонент Образ.java, который реализует интерфейс, соединяется со значком интерфейса (кружком) НаблюдательОбраза простой линией. Компонент РыцарьПечальногоОбраза.jауа, который использует интерфейс, связан с ним отношением зависимости.
Рис. 3.2 - Представление интерфейса в форме пиктограммы
Второй способ представления интерфейса иллюстрирует рис. 3.3. Здесь используется развернутая форма изображения интерфейса, в которой могут показываться его операции. Компонент, который реализует интерфейс, подключается к нему отношением реализации. Компонент, который получает доступ к услугам другого компонента через интерфейс, по-прежнему подключается к интерфейсу отношением зависимости.
Рис. 3.3 - Развернутая форма представления интерфейса
По способу связи компонента с интерфейсом различают:
экспортируемый интерфейс -- тот, который компонент реализует и предлагает как услугу клиентам;
импортируемый интерфейс -- тот, который компонент использует как услугу другого компонента.
У одного компонента может быть несколько экспортируемых и несколько импортируемых интерфейсов.
Тот факт, что между двумя компонентами всегда находится интерфейс, устраняет их прямую зависимость. Компонент, использующий интерфейс, будет функционировать правильно вне зависимости от того, какой компонент реализует этот интерфейс. Это очень важно и обеспечивает гибкую замену компонентов в интересах развития системы.
Построим компонентную диаграмму для клиент-серверного приложения «Интернет-аукцион». Из компонентов выделим две основные категории - скрипты, написанные на языках PHP и JavaScript, и файлы стилей CSS. Их будем помечать стереотипами script и CSS. Из категорий модулей исходного кода выделим три основные категории - модули работы с пользователями, с лотами и категориями лотов. Из связей в данной UML-модели используем заависимости между скриптами и файлами стилей, между главной страницей веб-приложения и страниц подсистем используем ассоциацию, так как эти файлы «знают о существовании друг друга». На рисунке3.4 приведена построенная компонентная диаграмма для веб-приложения «Интернет-аукцион».
Рис. 3.4 - Компонентная диаграмма для веб-приложения Интернет-аукцион
3.2 Диаграмма развертывания
Данный вид диаграмм в нотации UML моделирует размещение компонентов и артефактов системы на узлах и в контексте вычислительного окружения.
Выделим три узла вычислительных - веб- сервер, сервер базы данных и клиент, на котором размещен браузер. Диаграмму размещения построим в таких терминах, как устройства и компоненты. Компоненты и связи между ними сохраняются, очевидно, такие как и в диаграмме компонентов. На рисунке 3.5 приведена диаграмма развертывания веб-приложения «Интернет-аукцион».
Рис. 3.5 - Диаграмма развертывания веб-приложения
3.3 Интерфейс веб-приложения
В данном подразделе приведем интерфейс разработанного веб-приложения «Интернет-аукцион». Будем исходить из предположения, что систему использует Администратор и ставится задача задействовать весь функционал системы. На иллюстрациях будем приводит скриншоты интерфейса веб-приложения. Для написания инетерфейса использован востребованный фреймворк Bootstrap.
Главная страница приложения приведена на рисунке 3.6.
Рис. 3.6 - Главная страница веб-приложения
Далее, после успешного входа в систему Администратор попадает на страницу Личного кабинета, которая приведена на рисунке 3.7.
Рис. 3.7 - Внешний вид Личного кабинета веб-приложения
В Личном кабинете сосредоточен весь функционал веб-приложения. Из Личного кабинета Администратор может зайти в подсистему работы с пользователями, внешний вид которой приведен на рисунке 3.8.
Рисунок 3.8 - Подсистема работы с пользователями
В рамках данной подсистемы Администратор может создать нового пользователя. Внешний вид страницы создания нового пользователя приведен на рисунке 3.9.
Рис. 3.9 - Создание нового пользователя
Из списка пользователей Администратор может зайти также в редактирование существующего пользователя. Внешний вид страницы приведен на рисунке 3.10.
Рис. 3.10 - Редактирование существующего пользователя
Из Личного кабинета Администратор может воспользоваться функционалом работы с категориями. Страницы списка категорий и просмотра категории с лотами приведены на рисунках 3.11, 3.12.
Рис. 3.11 - Внешний вид страницы Просмотр категорий
Рисунок 3.11 - Внешний вид страницы Просмотр категории с лотами
Администратору из Личного кабинета доступна подсистема работы с лотами. В рамках данной подсистемы доступно создание и выставление лотов на аукцион. На рисунках 3.12, 3.13 приведены страницы списка лотов и просмотра лота.
Рис. 3.12 - Внешний вид страницы списка лотов
Рис. 3.13 - Страница просмотра отдельного лота
В данном подразделе мы рассмотрели интерфейс системы, типичный для веб-приложения. Сервер PHP не выдает ошибок ни на одной странице, следовательно, можно заключить, что приложение протестировано и функционирует согласно техническому заданию. Все исходные коды файлов стилей, скриптов и других файлов приведены в приложениях А, Б, В, Г.
Выводы. В данной главе были построены модели реализации веб-приложения аукциона. Был рассмотрен интерфейс пользователя, приведены веб-страницы фронтенда веб-аукциона.
ЗАКЛЮЧЕНИЕ
В данном дипломном проекте были рассмотрены инструментальные средства по созданию клиент-серверных веб-приложений.
Авторская часть диплома включает в себя разделы, посвященные проектированию и разработке веб-приложения «Интернет-аукцион». В разделах, посвященном проектированию и разработке веб-приложения, освещены вопросы логического проектирования будущего приложения, также вопросы разработки веб-приложения.
Дальнейшее развитие веб-приложения заключается в развитии дизайна, его адаптации под мобильные устройства, что является стандартом де-факто в настоящее время, различные дополнения существующего функционала для удобства пользования интернет-аукционом.
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
Сухов, К. HTML5 - путеводитель по технологии / К. Сухов. - М.: ДМК Пресс, 2013. - 352 с.: ил.
Дронов, В. А. HTML 5, CSS 3 и Web 2.0. Разработка современных Web-сайтов / В. А.Дронов. - СПб.: БХВ-Петербург, 2011. -- 416 с.: ил.
Чиртик, А.А. HTML. Популярный самоучитель / А.А. Чиртик. - СПб.: Питер, 2006. - 224с.: ил.
Мак-Дональд, М. HTML5. Недостающее руководство: Пер. с англ. / М. Мак-Дональд. - СПб.: БХВ-Петербург, 2012. - 480 с.: ил.
Петюшкин А. В. HTML. Экспресс-курс. -- СПб.: БХВ-Петербург, 2003. -- 256 с.: ил.
Дунаев, В. Сценарии для Web-сайта: PHP и JavaScript / В. Дунаев. - СПб.: БХВ-Петербург, 2008
Колисниченко, Д. Профессиональное программирование на PHP / Д. Колисниченко. - СПб.: BHV-Петербург, 2007
Кузнецов, М Объектно-ориентированное программирование на PHP / М. Кузнецов. - СПб.: BHV-Петербург, 2007
Колисниченко, Д. Профессиональное программирование на PHP / Д. Колисниченко. - СПб.: BHV-Петербург, 2007.
Кузнецов, М Объектно-ориентированное программирование на PHP / М. Кузнецов. - СПб.: BHV-Петербург, 2007
Дунаев, В. Самоучитель PHP / В. Дунаев. - СПб.: Питер, 2007
Дунаев, В. Сценарии для Web-сайта: PHP и JavaScript / В. Дунаев. - СПб.: БХВ-Петербург, 2008
Компания MySQL AB. MySQL. Руководство администратора.: Пер. с англ. - М.: Издательский дом 'Вильяме', 2005. - 624 с.
Веллинг, Л. MySQL. Учебное пособие.: Пер. с англ. / Люк Веллинг, Лора Томсон. - М.: Изд. дом «Вильямс», 2005. - 304с.: ил.
Херман, Д. Сила JavaScript. 68 способов эффективного использования JS / Д. Херман. - СПб.: Питер, 2013. - 288 с.: ил.
Флэнаган, Д. JavaScript. Подробное руководство, 6-е изд. Пер. с англ. / Д. Флэнаган - СПб: Символ Плюс, 2012. - 1080 с.: ил.
Моррисон, М. Изучаем JavaScript / М. Моррисон. - СПб.: Питер, 2012. - 608 с.: ил.
Терри, К. Визуальное моделирование с помощью IBM® Rational® Software Architect и UML™ / К. Терри, Д. Палистрант. - М., 2007. - 192 c.
Орлов, С. А. Технологии разработки программного обеспечения : учебник / С. А. Орлов. - СПб., 2004. - 527 c.
Буч, Г. Язык UML. Руководство пользователя / Г. Буч, Д. Рамбо Д., А. Джекобсон. - М., 2000. - 432 c.
Соммервилл, И. Инженерия программного обеспечения / И. Соммервил. - М., 2002. - 624 c.
ПРИЛОЖЕНИЕ А
Файлы стилей приложения
iv.cpanel{
display: block;
float: left;
height: 20%;
width: 98%;
margin: 2% 1% 4% 4%;
}
div.icon{
text-align: center;
float: left;
width: 30%;
}
input.error{
border: red solid 1px;
}
div.block{
display: block;
width: 100%;
}
body{background-color: #D9E3FF;}
a{
font-size: 12pt;
font-weight: bolder;
color: black;
}
tr:hover{
color: black;
background-color: #FFEFD5;
}
a:hover{
color: red;
}
input[type='text'], input[type='password'], select{
margin: 2px 6px 4px 10px;
border: solid blue 1px;
border-radius: 4px;
/***** BASE CSS *****/
/* Site Name */
#divSiteTitle {text-decoration:none;}
#divTagLine {text-decoration:none;}
/* Headline Text */
#divHeaderLine1 {display:inline-block !important}
#divHeaderLine2 {display:inline-block !important}
#divHeaderLine3 {display:inline-block !important}
/* Headings */
h3, h4, h5, h6 {line-height:1.5 !important}
.lead {
text-align:center;
}
.lead h2 {
font-size:33px;line-height:45px;
}
.lead h3 {
font-size:17px;
}
.lead h3 a {
font-size:inherit !important;
}
/* Contact */
ul#contact-info .icon {font-size:20px;float:left;line-height:25px;margin-right:10px;}
ul#contact-info .field {font-weight:bold;}
ul#contact-info {list-style:none;}
/* Grid */
#tiles li {
width:240px !important;
background-color: #ffffff;
border: 1px solid #dedede;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
padding: 10px !important;
margin-right:7px;margin-bottom:7px;float:left;
}
#tiles li img {margin-bottom:10px;}
#tiles li div.meta {color:#999;text-transform:uppercase;font-size:10px;margin:0;}
#tiles li h4 {line-height:1.5;margin:0 0 5px 0;}
#tiles li h4 a {line-height:inherit;margin:0;text-decoration:inherit;color:inherit;font-size:inherit;font-family:inherit;font-weight:inherit;font-style:inherit;}
#tiles li p {font-size:12px;line-height:1.5;margin:0;}
#tiles li a {font-size:12px;}
#tiles li .more_link {font-size:smaller;line-height:2;text-transform:uppercase;letter-spacing:2px;white-space:nowrap;display:block;margin: 5px 0 0 0;}
#tiles li blockquote {line-height:1.5;margin:0;padding:0;color:#999;border:none;font-size:150%;font-style:italic;font-family:Georgia, Times, serif;}
#tiles li blockquote small {font-size:11px;font-style:normal;}
/* Icons */
[class*='social foundicon-']:before {font-family: 'SocialFoundicons';}
[class*='general foundicon-']:before {font-family: 'GeneralFoundicons';}
/* Menu Side */
.menu_menu_simple ul {margin-top:0px;margin-bottom:0px;}
.menu_menu_simple ul li {margin-top:0px;margin-bottom:0px;}
/* Header Area */
#decorative1 {
margin-top:-2px;padding-top:2px;
}
/* Menu Centered */
.centered_menu {text-align:center}
.centered_menu > div {display:inline-block;}
.centered_menu div {text-align:left}
/* Footer elements */
.social_bookmarks a {font-size:smaller !important;text-transform:uppercase;letter-spacing:1px;text-decoration:none;margin-right:20px;}
.copyright {font-size:smaller;letter-spacing:1px;}
/* Responsive Image */
img {max-width:100%;height:auto;width:auto;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;}
/* Responsive Video from Zurb Foundation. Copyright (c) 2011 ZURB, http://www.zurb.com/ License: MIT */
.flex-video {position:relative;padding-top:25px;padding-bottom:67.5%;height:0;margin-bottom:16px;overflow: hidden;}
.flex-video.widescreen {padding-bottom:57.25%;}
.flex-video.vimeo {padding-top:0;}
.flex-video iframe, .flex-video object, .flex-video embed {position:absolute;top:0;left:0;width:100%;height:100%;border:none;}
@media only screen and (max-device-width: 800px), only screen and (device-width: 1024px) and (device-height: 600px), only screen and (width: 1280px) and (orientation: landscape), only screen and (device-width: 800px), only screen and (max-width: 767px) {
.flex-video { padding-top: 0; }
}
/* Additional */
#divBoxed {position:relative}
.nav-links > a {margin-right:20px;}
.btn-secondary, .btn-secondary:hover {text-shadow:none;}
#divHeaderLine1 a, #divHeaderLine2 a, #divHeaderLine3 a {
font-size: inherit;
line-height: inherit;
letter-spacing: inherit;
font-family: inherit;
text-shadow: inherit;
font-weight: inherit;
font-style: inherit;
}
#divHeaderLine1, #divHeaderLine2, #divHeaderLine3 {
padding-top:3px !important;
padding-bottom:3px !important;
text-align:inherit !important;
}
#decorative2 {/*opacity:0.95;*/
-webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.03);
-moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.03);
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.03);
}
.showcase-tabs > li > a {
font-size: 14px;
letter-spacing: 1px;
padding-left: 20px;
padding-right: 20px;
}
.cap1 div, .cap2 div, .cap3 div, .cap4 div, .cap5 div {
margin: 0 -1px;
}
.camera_wrap .camera_pag .camera_pag_ul li {margin:20px 5px 0px !important;
}
/* Adjustments */
.search.adjust {margin-bottom:15px}
.divPanel {}
.divPanel.notop {padding-top:0px}
.divPanel.nobottom {padding-bottom:0px}
/***** BOOTSTRAP CSS BASE OVERRIDE *****/
.navbar .nav-pills > li > a {text-shadow:none;font-weight:normal;}
.navbar .dropdown-menu li > a {text-shadow:none;font-weight:normal;}
.navbar .nav-pills > li > .dropdown-menu:before {border:none;}
.navbar .nav-pills > li > .dropdown-menu:after {border:none;}
.navbar .nav-pills > .active > a, .navbar .nav-pills > .active > a:hover, .navbar .nav-pills > .active > a:focus {-webkit-box-shadow: none;box-shadow: none;}
.navbar .nav-pills > li > a:hover, .navbar .nav-pills li.dropdown.open.active > .dropdown-toggle {-webkit-transition: ease-in-out .2s;-moz-transition: ease-in-out .2s;-o-transition: ease-in-out .2s;-ms-transition: ease-in-out .2s; transition: ease-in-out .2s;}
.navbar .nav-pills .open .dropdown-toggle {background-color:transparent;}
.btn .caret {margin-top: 8px !important;}
body{background-image: none; background-position: initial initial; background-repeat: initial initial; }
#divLogo{margin-top: 9px; margin-bottom: 0px; margin-left: -3px;}
#divSiteTitle{font-family: 'Century Gothic', sans-serif; color: rgb(255, 255, 255); font-size: 28px; text-shadow: none; line-height: 42px; letter-spacing: 2px; text-transform: uppercase; font-weight: normal; font-style: normal;}
#divTagLine {font-family: 'Century Gothic', sans-serif; font-size: 12px; text-transform: uppercase; letter-spacing: 5px; line-height: 22px; color: rgb(255, 255, 255); text-shadow: none; padding-left: 3px; padding-right: 3px; font-weight: normal; font-style: normal;}
.navContainer {margin-top: 0px; }
.navContainer .navMenu {}
.navContainer .navMenu li {background-color: rgb(245, 245, 245); border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; }
.navContainer .navMenu li a {}
.navContainer .navMenu li.current {background-color: rgb(174, 0, 0); }
.navContainer .navMenu li.current a {}
.camera_caption > div {opacity: 0.85;filter:alpha(opacity=85);opacity: 0.85;filter:alpha(opacity=85);}
.camera_prevThumbs, .camera_nextThumbs, .camera_prev, .camera_next, .camera_commands, .camera_thumbs_cont {opacity: 0.85;filter:alpha(opacity=85);opacity: 0.85;filter:alpha(opacity=85);}
.camera_wrap .camera_pag .camera_pag_ul li, .camera_wrap .camera_pag .camera_pag_ul li, .camera_wrap .camera_pag .camera_pag_ul li:hover > span {box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);}
.camera_wrap .camera_pag .camera_pag_ul li.cameracurrent > span {}
.camera_wrap {display: block; margin-bottom: 15px; height: 410px; border: 5px solid rgb(255, 255, 255); margin-left: -5px; -webkit-box-shadow: rgba(0, 0, 0, 0.294118) 0px 1px 4px; box-shadow: rgba(0, 0, 0, 0.294118) 0px 1px 4px; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; margin-top: 44px;}
.cap1 > div {opacity: 0.85;filter:alpha(opacity=85);opacity: 0.85; background-color: rgb(212, 173, 0); }
.cap2 > div {opacity: 0.85;filter:alpha(opacity=85);opacity: 0.85; background-color: rgb(212, 173, 0); }
.cap3 > div {opacity: 0.85;filter:alpha(opacity=85);opacity: 0.85;filter:alpha(opacity=85);}
.cap4 > div {opacity: 0.85;filter:alpha(opacity=85);opacity: 0.85;filter:alpha(opacity=85);}
.cap5 > div {opacity: 0.85;filter:alpha(opacity=85);opacity: 0.85;filter:alpha(opacity=85);}
h1 {font-family: 'Source Sans Pro', sans-serif; font-weight: normal; font-style: normal; font-size: 40px; line-height: 65px; margin-top: 0px; color: rgb(0, 0, 0);}
.page-content {line-height: 25px; font-family: 'Open Sans', sans-serif;}
.page-content a {color: rgb(60, 160, 91); font-family: 'Open Sans', sans-serif;}
.sidebox {-webkit-box-shadow:rgba(0, 0, 0, 0.298039) 0px 1px 3px;-moz-box-shadow:rgba(0, 0, 0, 0.298039) 0px 1px 3px;box-shadow:rgba(0, 0, 0, 0.298039) 0px 1px 3px;background-color:rgb(250, 250, 250);color:rgb(51, 51, 51);border-width:1px;border-style:solid;border-color:rgb(255, 255, 255);border-radius:3px;padding:18px;margin-top:28px;}
.sidebar {;}
.sidebox-title {line-height: 40px; font-weight: normal; font-style: normal; font-family: 'Source Sans Pro', sans-serif; color: rgb(51, 51, 51);}
.sidebox a{color: rgb(54, 150, 86);}
#decorative1{position: relative; background-color: rgb(240, 240, 240); background-image: url(bob-van-aubel-ray-bans.jpg); -webkit-background-size: cover; background-size: cover; background-position: 50% 50%; background-repeat: no-repeat no-repeat;
-webkit-box-shadow: 0px 3px 11px rgba(0, 0, 0, 0.7);
-moz-box-shadow: 0px 3px 11px rgba(0, 0, 0, 0.7);
box-shadow: 0px 3px 11px rgba(0, 0, 0, 0.7);}
#decorative2{background-color: rgb(64, 172, 98); height: 85px;}
#divFooter{font-family: 'Open Sans', sans-serif; background-color: transparent; color: rgb(41, 41, 41); padding-top: 32px; line-height: 22px; font-size: 12px; text-transform: none; background-image: url(chruch.png); background-repeat: repeat repeat;}
#divFooter a{color: rgb(54, 150, 86);}
#divFooter h3{color: rgb(41, 41, 41);}
h2 {font-weight: normal; font-style: normal; font-family: 'Source Sans Pro', sans-serif; font-size: 35px; line-height: 45px;}
.breadcrumbs {line-height: 80px; font-family: 'Open Sans', sans-serif;}
.breadcrumbs a {color: rgb(60, 160, 91); font-family: 'Open Sans', sans-serif;}
#divHeaderLine1{
letter-spacing: 0px;
word-spacing: 0px;
margin-top: 0px;
color: rgb(51,51,51);
font-size: 50px;
line-height: 64px;
font-family: 'Source Sans Pro', sans-serif;
text-transform: none;
text-shadow: rgba(0, 0, 0, 0.14902) 0px 3px 5px, rgba(255, 255, 255, 0.298039) 0px -5px 35px;
font-weight: normal;
font-style: normal;
text-align: center;
background-color: rgb(255,255,255);
opacity: 0.9;
padding: 3px 10px;
}
#divHeaderLine2 {font-size: 20px; line-height: 30px; letter-spacing: 1px; margin-top: 11px; font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, serif; color: rgb(255, 255, 255); text-shadow: none; text-align: center; font-weight: normal; font-style: italic; background-color: rgb(0, 0, 0); opacity: 0.9; padding: 3px 10px; background-position: initial initial; background-repeat: initial initial;}
#divHeaderLine3{margin-top: 18px; color: rgb(0, 0, 0); text-align: center; line-height: 16px; text-transform: none; font-size: 15px;}
a.btn, a.btn-large, a.btn-small, a.btn-mini {color:#333}
a.btn-info, a.btn-success, a.btn-warning, a.btn-danger, a.btn-inverse {color:#ffffff}
.btn-secondary, .btn-secondary:hover, a.btn-secondary, a.btn-secondary:hover {color:#323232;}
.btn-secondary {border:1px solid #dfdfdf;border-bottom:1px solid #afafaf;background-color:#fafafa;background-repeat: repeat-x;background-image:-webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#e1e1e1));background-image:-webkit-linear-gradient(top, #fafafa, #e1e1e1);background-image:-moz-linear-gradient(top, #fafafa, #e1e1e1);background-image:-ms-linear-gradient(top, #fafafa, #e1e1e1);background-image:-o-linear-gradient(top, #fafafa, #e1e1e1);background-image:linear-gradient(top, #fafafa, #e1e1e1);filter: progid:dximagetransform.microsoft.gradient(startColorstr=#fafafa, endColorstr=#e1e1e1, GradientType=0);filter: progid:dximagetransform.microsoft.gradient(enabled=false);}
.btn-secondary:hover, .btn-secondary:active, .btn-secondary.active, .btn-secondary.disabled, .btn-secondary[disabled] {background-color:#dfdfdf;}
.btn-primary, .btn-primary:hover, a.btn-primary, a.btn-primary:hover {color:#ffffff;}
.btn-primary {border:1px solid #399957;border-bottom:1px solid #2d7845;background-color:#40ac62;background-repeat: repeat-x;background-image:-webkit-gradient(linear, left top, left bottom, from(#40ac62), to(#3a9b58));background-image:-webkit-linear-gradient(top, #40ac62, #3a9b58);background-image:-moz-linear-gradient(top, #40ac62, #3a9b58);background-image:-ms-linear-gradient(top, #40ac62, #3a9b58);background-image:-o-linear-gradient(top, #40ac62, #3a9b58);background-image:linear-gradient(top, #40ac62, #3a9b58);filter: progid:dximagetransform.microsoft.gradient(startColorstr=#40ac62, endColorstr=#3a9b58, GradientType=0);filter: progid:dximagetransform.microsoft.gradient(enabled=false);}
.btn-primary:hover, .btn-primary:active, .btn-primary.active, .btn-primary.disabled, .btn-primary[disabled] {background-color:#399957;}
#divHeaderText {padding-top: 200px; padding-bottom: 30px; border-color: rgb(51, 51, 51); text-align: left;}
#decorative2{background-image:-moz-linear-gradient(bottom,#369656,#40ac62);background-image:-o-linear-gradient(bottom,#369656,#40ac62);background-image:-webkit-gradient(linear,left top, left bottom,from(#369656),to(#40ac62));background-image:-webkit-linear-gradient(bottom,#369656,#40ac62);background-image:linear-gradient(to bottom,#40ac62,#369656);background-image:linear-gradient(bottom,#369656,#40ac62);}
#contentOuterSeparator{margin-top: 0px; border-top-color: rgb(255, 255, 255); border-top-width: 0px; border-top-style: solid; margin-bottom: 25px; height: 0px; background-color: transparent;}
#footerOuterSeparator{margin-top: 55px; border-top-width: 0px; border-top-style: solid; border-top-color: rgb(95, 95, 95);}
#headerSeparator{margin-top: 7px; border-top-color: rgb(51, 51, 51); border-top-width: 0px; border-top-style: solid;}
h3,.page-content h3 a {font-weight: normal; font-style: normal; font-family: 'Source Sans Pro', sans-serif; font-size: 28px; line-height: 45px;}
h4,.page-content h4 a {font-weight: normal; font-style: normal; font-family: 'Source Sans Pro', sans-serif; font-size: 21px; line-height: 45px;}
h5,.page-content h5 a {font-weight: normal; font-style: normal; font-family: 'Source Sans Pro', sans-serif; font-size: 17px; line-height: 45px;}
h6,.page-content h6 a {font-weight: normal; font-style: normal; font-family: 'Source Sans Pro', sans-serif; font-size: 15px; line-height: 45px;}
.line-separator{border-top-width: 1px; border-top-style: solid; margin-top: 21px; margin-bottom: 21px; border-top-color: rgb(234, 234, 234); border-bottom-color: rgb(255, 255, 255); border-bottom-width: 1px; border-bottom-style: solid; }
#headerSeparator2{margin-top: 45px; margin-bottom: 18px; }
#divVideo{border: 7px solid rgb(255, 255, 255); margin-left: -5px; -webkit-box-shadow: rgba(0, 0, 0, 0.498039) 0px 15px 10px -10px, rgba(0, 0, 0, 0.298039) 0px 1px 4px; box-shadow: rgba(0, 0, 0, 0.498039) 0px 15px 10px -10px, rgba(0, 0, 0, 0.298039) 0px 1px 4px; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; margin-top: 36px; }
.nav .dropdown-toggle .caret {border-top-color:rgb(0, 0, 0);border-bottom-color:rgb(0, 0, 0);}
.nav .dropdown-toggle:hover .caret {border-top-color:rgb(0, 0, 0);border-bottom-color:rgb(0, 0, 0);}
.navbar .dropdown-menu, .dropdown-menu {background-color: rgb(54, 54, 54); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;}
.navbar .dropdown-menu li > a, .dropdown-menu li > a, .navbar .nav-pills .open .dropdown-toggle {color: rgb(255, 255, 255);}
.navbar .dropdown-menu li > a:hover, .navbar .dropdown-menu .active > a, .navbar .dropdown-menu .active > a:hover, .dropdown-menu li > a:hover, .dropdown-menu .active > a, .dropdown-menu .active > a:hover, .dropdown-menu li > a:focus, .dropdown-submenu:hover > a, .navbar .nav-pills .open a.dropdown-toggle:hover {filter:none;color:rgb(255, 255, 255);background-color:rgb(54, 150, 86);background-image:none}
.navbar .nav-pills > li > a {margin-left: 2px; margin-right: 2px; padding: 35px; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; color: rgb(255, 255, 255); border-bottom-style: none;}
.navbar .nav-pills > li > a:hover, .navbar .nav li.dropdown.open.active > .dropdown-toggle, .navbar .nav-pills > li > a:focus {color: rgb(255, 255, 255); background-color: rgb(64, 172, 98); border-bottom-style: none;}
.navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav li.dropdown.open > .dropdown-toggle, .navbar .nav li.dropdown.active > .dropdown-toggle {background:none}
.navbar .nav-pills > .active > a, .navbar .nav-pills > .active > a:hover, .navbar .nav-pills li.dropdown.open > .dropdown-toggle, .navbar .nav-pills li.dropdown.active > .dropdown-toggle {color: rgb(255, 255, 255); background-color: rgb(64, 172, 98); border-bottom-style: none;}
.navbar .ddmenu {margin-top:-2px;margin-bottom:0px}
.navbar .nav-pills li.dropdown > .dropdown-toggle .caret, .navbar .nav-pills li.dropdown.open > .dropdown-toggle .caret, .navbar .nav-pills li.dropdown.active > .dropdown-toggle .caret, .navbar .nav-pills li.dropdown.open.active > .dropdown-toggle .caret {border-top-color:rgb(255, 255, 255);border-bottom-color:rgb(255, 255, 255);}
.navbar .nav-pills li.dropdown > .dropdown-toggle:hover .caret {border-top-color:rgb(255, 255, 255);border-bottom-color:rgb(255, 255, 255);}
.navbar .nav-pills li.dropdown.active > .dropdown-toggle .caret {border-top-color:rgb(255, 255, 255);border-bottom-color:rgb(255, 255, 255);}
.dropdown-menu .sub-menu {left:100%;position:absolute;top:0;visibility:hidden;margin-top:-1px;}
.dropdown-menu li:hover .sub-menu {visibility:visible;}
.ddmenu.nav-pills li a {font-family: Abel, sans-serif; font-size: 17px; text-shadow: none; line-height: 15px;}
.ddmenu .dropdown-menu li a{line-height: 29px; font-size: 15px;}
#decorative2 {position:fixed;top:0;left:0;right:0;z-index:1032}
body {padding-top:85px}
.lead h2 {font-size: 37px; line-height: 57px; font-family: 'Open Sans';}
.lead h3 {font-size: 21px; line-height: 31px;}
.dropdown-menu .sub-menu {left:100%;position:absolute;top:0;visibility:hidden;margin-top:-1px;}
.dropdown-menu li:hover .sub-menu {visibility:visible;}
.navbar .btn-navbar-highlight {display:none;width:100%}
#decorative2 {z-index:100 !important}
@media (max-width: 979px) {
#divLogo {margin-bottom:10px;}
.navbar .btn-navbar-highlight {display:inline;padding:9px 14px;margin-top:15px;}
.navbar {width:100%;}
#divMenuRight {float:none}
.dropdown-menu .sub-menu {left:0%;position:relative;top:0;visibility:visible;margin-top:3px;display:block}
.dropdown-menu, .sub-menu {border-radius:5px !important;}
.navbar .ddmenu {margin-top: 0px;margin-bottom: 0px;}
/* Fixed Top */
#decorative2 {position:static; height:auto;}
body {padding-top:0px}
}
@media (max-width: 767px) {
#divLogo {margin-top:10px;margin-bottom:10px;}
#divSiteTitle {font-size: 25px;}
#divHeaderText {margin:0px;padding:10px 0px;}
#divHeaderLine1 {margin-top: 0px;}
#divMenuRight {width:100%;margin-top: 0px;padding-top:0px}
.ddmenu, .navbar .ddmenu {margin-top: 0px; margin-bottom: 0px;}
.navbar .btn-navbar-highlight {padding:9px 14px;margin-top:0px;}
.navbar {width:100%;margin-top: 0px;padding-top:0px}
#decorative1, #decorative2, #decorative3 {margin-left:-20px;margin-right:-20px;padding-left:20px;padding-right:20px;}
/* Fixed Top */
#decorative2 {position:static}
body {padding-top:0px}
#divFooter {margin-left:-20px;margin-right:-20px;padding-left:20px;padding-right:20px;}
#divBoxed > #divFooter {margin-left:0px;margin-right:0px;padding-left:0px;padding-right:0px;}
body > #footerOuterSeparator, body > #contentOuterSeparator {margin-left:-20px;margin-right:-20px;}
.headerArea, .topArea {padding:20px !important;}
/*only for templates without divBoxed*/
#camera_wrap {margin-top:20px}
#divVideo {margin-top:20px}
.dropdown-menu .sub-menu {left:0%;position:relative;top:0;visibility:visible;margin-top:3px;display:block}
.dropdown-menu, .sub-menu {border-radius:5px !important;}
.navbar .ddmenu {margin-top: 0px;margin-bottom: 0px;}
}
}
ПРИЛОЖЕНИЕ Б
Листинги модулей PHP подсистемы работы с категориями
<?php
defined('INTERNAL') or die();
$current = $_SESSION['user'];
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT id,name FROM categories WHERE parent=0 LIMIT 0,30';
$result = mysqli_query($dblink, $query);
$options = '';
while($row = $result->fetch_assoc()){
$options .= '<option value='$row[id]'>$row[name]</option>';
}
$result->free_result();
mysqli_close($dblink);
header('Content-Type: text/html;charset=utf-8');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Создание категории</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form action='index.php' method='post' enctype='application/x-www-form-urlencoded'>
<table>
<thead><tr><th width='10%'></th><th width='40%'></th></tr></thead>
<tbody>
<tr><td>Название</td><td><input type='text' size='40' maxlength='40' name='name' /></td></tr>
<tr><td>Родительская категория</td><td><select name='parent'><option value='0'>Не задано</option><?php echo $options; ?></select></td></tr>
</tbody></table>
<input type='hidden' name='act' value='create' />
<input type='submit' value='Создать' />
</form>
</div>
<div class='icon' style='padding-top : 27px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php
defined('INTERNAL') or die();
$current = $_SESSION['user'];
if (!isset($_GET['id'])){header('Location: index.php'); exit;}
$id = $_GET['id'];
if (!preg_match('/^[0-9]+$/', $id)){header('Location: index.php'); exit;}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT * FROM categories WHERE id=$id';
$result = mysqli_query($dblink, $query);
$record = $result->fetch_assoc();
$result->free_result();
$options = '';
if ($record['parent'] != '0'){
$query = 'SELECT id,name FROM categories WHERE parent=0';
$result = mysqli_query($dblink, $query);
while($row = $result->fetch_assoc()) $options .= '<option value='$row[id]'>$row[name]</option>';
$result->free_result();
}
mysqli_close($dblink);
header('Content-Type: text/html;charset=utf-8');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Редактирование категории</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form action='index.php' method='post' enctype='application/x-www-form-urlencoded'>
<table>
<thead><tr><th width='10%'></th><th width='40%'></th></tr></thead>
<tbody>
<tr><td>Название</td><td><input type='text' size='40' maxlength='40' name='name' value='<?php echo $record['name']; ?>' /></td></tr>
<tr><td>Родительская категория</td><td><select name='parent'><option value='0'>Не задано</option><?php echo $options; ?></select></td></tr>
</tbody></table>
<input type='hidden' name='act' value='save' />
<input type='hidden' name='id' value='<? echo $id; ?>' />
<input type='submit' value='Сохранить' />
</form>
</div>
<div class='icon' style='padding-top : 27px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php
define('INTERNAL',1);
require_once('../login/code.php');
if (requireLogin()) {header('Location: /index.php', 1, 301); exit;}
header('Content-Type: text/html;charset=utf-8');
$user = $_SESSION['user'];
$rights = array('user'=>1,'editor'=>2,'moder'=>3,'admin'=>4);
$right = $rights[$user['rights']];
$method = $_SERVER['REQUEST_METHOD'];
if ($right<2) {header('Location: /mod/admin', 1, 301); exit;}
require_once('../../config.php');
if ($method == 'POST'){ processPost(); exit; }
$act = '';
if (isset($_GET['act'])) $act = $_GET['act'];
if (in_array($act, array('create', 'edit', 'view', 'delete'))){
require_once('$act.php'); exit;
}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT * FROM categories LIMIT 0,30';
$result = mysqli_query($dblink, $query);
$keys = array('id', 'name', 'parent', 'level');
$thead = ''; $tbody = '';
$labels = array('id', 'Название', 'Родительская категория', 'Уровень');
foreach ($labels as $key){
$thead .= '<th>$key</th>';
}
for ($i=0;$i<$result->num_rows;$i++){
$record = $result->fetch_assoc();
$idd = $keys[0];
$tbody .= '<tr align='center'>';
foreach ($keys as $key){
if ($key == 'name')
$tbody .= '<td><a href='?act=view&id=$record[$idd]'>$record[$key]</a></td>';
else $tbody .= '<td>$record[$key]</td>';
}
$tbody .= '</tr>';
}
$result->free_result();
mysqli_close($dblink);
header('Content-Type: text/html;charset=utf-8');
$output = true;
if ($output):
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Категории</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div>
<table>
<thead><tr><?php echo $thead; ?></tr></thead>
<tbody><?php echo $tbody; ?></tbody>
</table>
</div>
<div><a href='?act=create'>Создать</a></div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php endif;
function processPost(){
global $config;
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$args = array('db'=>$dblink);
if (isset($_POST['act'])) $act = $_POST['act'];
if ($act == 'save') saveCategory($args);
if ($act == 'create') createCategory($args);
if ($act == 'list') listCategories($args);
mysqli_close($dblink);
}
function createCategory($args){
$dblink = $args['db'];
if (!isset($_POST['name']) || !isset($_POST['parent'])) return;
$name = $_POST['name']; $parent = $_POST['parent'];
if (!preg_match('/^[0-9]+$/', $parent)) return;
$name = mysqli_real_escape_string($dblink, $name);
$query = 'INSERT INTO categories (`name`, `parent`, `level`)
VALUES('$name', $parent, 0)';
mysqli_query($dblink, $query);
header('Location: index.php', 1, 301);
}
function saveCategory($args){
$dblink = $args['db'];
if (!isset($_POST['name']) || !isset($_POST['parent']) || !isset($_POST['id'])) return;
$name = $_POST['name'];
$id = $_POST['id'];
$parent = $_POST['parent'];
if (!preg_match('/^[0-9]+$/', $parent) || !preg_match('/^[0-9]+$/', $id)) return;
$name = mysqli_real_escape_string($dblink, $name);
$query = 'UPDATE categories SET `name`='$name', `parent`=$parent WHERE id=$id';
mysqli_query($dblink, $query);
header('Location: index.php', 1, 301);
}
function listCategories($args){
$dblink = $args['db'];
$output = array();
if (!isset($_POST['parent'])) return;
$parent = $_POST['parent'];
if (!preg_match('/^[0-9]+$/', $parent)) return;
$query = 'SELECT * FROM categories WHERE parent=$parent';
$result = mysqli_query($dblink, $query);
while ($row = $result->fetch_assoc()) $output[] = $row;
$result->free_result();
echo json_encode($output);
}
?>
<?php
defined('INTERNAL') or die();
$current = $_SESSION['user'];
if (!isset($_GET['id'])){header('Location: index.php'); exit;}
$id = $_GET['id'];
if (!preg_match('/^[0-9]+$/', $id)){header('Location: index.php'); exit;}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT id, name, parent FROM categories WHERE id=$id';
$result = mysqli_query($dblink, $query);
$cat = $result->fetch_assoc();
$result->free();
$query = 'SELECT id, name FROM categories WHERE id=$cat[parent]';
$result = mysqli_query($dblink, $query);
$cat = array($cat, $result->fetch_assoc());
$result->free();
$row = $cat[0];
$category = '<td><a href='?act=edit&id=$row[id]'>$row[name]</a></td>';
$row = $cat[1];
$parent = '<td>-Нет-</td>';
if ($row) $parent = '<td><a href='?act=view&id=$row[id]'>$row[name]</a></td>';
$category .= $parent;
$query = 'SELECT l.id, l.name, l.images, u.firstname, u.lastname FROM lots l, users u
WHERE l.category=$id AND u.id=l.organizer';
$lots = '';
$result = mysqli_query($dblink, $query);
while ($row = $result->fetch_assoc()) {
$images = explode(';',$row['images']);
$img = $images[0];
if ($img == '') $img = '-Нету-';
else $img = '<img src='/images/data/$img[0]$img[1]/$img[2]$img[3]/$img'
width='100' height='100' />';
$lots .= '<tr align='center'><td>$row[id]</td><td><a href='/mod/lots/?act=view&id=$row[id]'>$row[name]</a></td>
<td>$img</td><td>$row[firstname] $row[lastname]</td></tr>';
};
$result->free();
mysqli_close($dblink);
header('Content-Type: text/html;charset=utf-8');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Просмотр категории</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<table>
<thead><tr><th width='10%'>Название</th><th width='20%'>Родительская категория</th></tr></thead>
<tbody><tr align='center'>
<?php echo $category; ?>
</tr></tbody></table>
<p>Лоты категории</p>
<table>
<thead><tr><th>Id</th><th>Название</th><th>Изображение</th><th>Организатор</th></tr></thead>
<tbody><?php echo $lots; ?></tbody>
</table>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
ПРИЛОЖЕНИЕ В
Модули подсистемы работы с лотами
<?php
defined('INTERNAL') or die();
$current = $_SESSION['user'];
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT id,name FROM categories WHERE parent=0';
$result = mysqli_query($dblink, $query);
$options = '';
while($row = $result->fetch_assoc()){
$options .= '<option value='$row[id]'>$row[name]</option>';
}
$result->free_result();
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='createlot.init();'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Создание лота</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form id='create' action='index.php' method='post' enctype='multipart/form-data'>
<table>
<thead><tr><th width='20%'></th><th width='40%'></th></tr></thead>
<tbody>
<tr><td>Название лота</td><td><input type='text' size='60' maxlength='60' name='name' /></td></tr>
<tr><td>Корневая категория</td><td><select name='root-cat'><option value='0'>Не задано</option><?php echo $options; ?></select></td></tr>
<tr><td>Категория лота</td><td><select name='category'></select></td></tr>
<tr><td>Описание лота</td><td><textarea cols='40' rows='5' name='description'></textarea></td></tr>
<tr><td>Тип лота</td><td>
Фиксированная цена<input type='radio' name='lottype' value='fixed' checked='' />
Аукцион<input type='radio' name='lottype' value='auction' /></td></tr>
<tr style='visibility:hidden;'><td>Тип аукциона</td><td>
Открытый<input type='radio' name='auctiontype' value='public' checked='' />
Закрытый<input type='radio' name='auctiontype' value='private' />
</td></tr>
<tr><td>Цена объекта</td><td><input type='text' size='30' maxlength='60' name='cost' /></td></tr>
<tr style='visibility: hidden;'><td>Шаг торгов</td><td><input type='text' size='30' maxlength='60' name='step' /></td></tr>
<tr style='visibility: hidden;'><td>Начало торгов</td><td><input type='text' size='30' maxlength='60' name='startdate' /></td></tr>
<tr style='visibility: hidden;'><td>Конец торгов</td><td><input type='text' size='30' maxlength='60' name='enddate' /></td></tr>
<tr><td>Первый файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Второй файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Третий файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Четвёртый файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Пятый файл</td><td><input type='file' name='images[]' /></td></tr>
</tbody></table>
<input type='hidden' name='act' value='create' />
<input type='submit' value='Создать' />
</form>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php
defined('INTERNAL') or die();
$current = $_SESSION['user'];
$id = '';
if (!isset($_GET['id'])){header('Location: index.php', true, 301); exit;}
$id = $_GET['id'];
if (!preg_match('/^[0-9]+$/', $id)){header('Location: index.php', true, 301); exit;}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT id FROM `order` WHERE lot=$id';
$result = mysqli_query($dblink, $query);
$row = $result->fetch_assoc();
$result->free_result();
$selt = $row?true:false;
$query = 'SELECT id,name FROM categories WHERE parent=0';
$result = mysqli_query($dblink, $query);
$options = '';
while($row = $result->fetch_assoc()){
$options .= '<option value='$row[id]'>$row[name]</option>';
}
$result->free_result();
$query = 'SELECT lots.id, lots.name, images, lots.description,
lots.auctiontype, lots.lottype, lots.startdate, lots.enddate,
lots.cost, lots.step, lots.organizer, cat.name AS category
FROM lots, categories cat WHERE lots.id=$id AND cat.id=lots.category';
$result = mysqli_query($dblink, $query);
echo mysqli_error($dblink);
$record = $result->fetch_assoc();
$result->free();
mysqli_close($dblink);
if (!$record || $record['organizer'] != $current['id'] && $current['rights'] != 'admin'){
header('Location: index.php', true, 301); exit;
}
$record['startdate'] = date('d.m.Y H:i:s', $record['startdate']);
$record['enddate'] = date('d.m.Y H:i:s', $record['enddate']);
$record['cost'] = number_format((float)$record['cost'], 3, '.', '');
$record['step'] = number_format((float)$record['step'], 3, '.', '');
$record['description'] = htmlentities($record['description']);
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='editlot.init();'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Редактирование лота</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form id='create' action='index.php' method='post' enctype='multipart/form-data'>
<table>
<thead><tr><th width='20%'></th><th width='40%'></th></tr></thead>
<tbody>
<?php if ($selt):?>
<tr><td><b>Товар продан</b></td><td></td></tr>
<?php else:?>
<tr><td>Название лота</td><td><input type='text' size='60' maxlength='60' name='name' value='<?php echo $record['name']; ?>' /></td></tr>
<tr><td>Корневая категория</td><td><select name='root-cat'><option value='0'>Не задано</option><?php echo $options; ?></select></td></tr>
<tr><td>Категория лота</td><td><select name='category'></select></td></tr>
<tr><td>Описание лота</td><td><textarea cols='40' rows='5' name='description'><?php echo $record['description']; ?></textarea></td></tr>
<tr><td>Тип лота</td><td>
Фиксированная цена<input type='radio' name='lottype' value='fixed' checked='' />
Аукцион<input type='radio' name='lottype' value='auction' /></td></tr>
<tr style='visibility:hidden;'><td>Тип аукциона</td><td>
Открытый<input type='radio' name='auctiontype' value='public' checked='' />
Закрытый<input type='radio' name='auctiontype' value='private' />
</td></tr>
<tr><td>Цена объекта</td><td><input type='text' size='30' maxlength='60' name='cost' value='<?php echo $record['cost']; ?>' /></td></tr>
<tr style='visibility: hidden;'><td>Шаг торгов</td><td><input type='text' size='30' maxlength='60' name='step' value='<?php echo $record['step']; ?>' /></td></tr>
<tr style='visibility: hidden;'><td>Начало торгов</td><td><input type='text' size='30' maxlength='60' name='startdate' value='<?php echo $record['startdate']; ?>' /></td></tr>
<tr style='visibility: hidden;'><td>Конец торгов</td><td><input type='text' size='30' maxlength='60' name='enddate' value='<?php echo $record['enddate']; ?>' /></td></tr>
<tr><td>Первый файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Второй файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Третий файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Четвёртый файл</td><td><input type='file' name='images[]' /></td></tr>
<tr><td>Пятый файл</td><td><input type='file' name='images[]' /></td></tr>
<?php endif;?>
</tbody></table>
<input type='hidden' name='act' value='update' />
<input type='hidden' name='id' value='<?php echo $record['id']; ?>' />
<?php if (!$selt):?>
<input type='submit' value='Сохранить' />
<?php endif;?>
</form>
<div><a href='index.php'>Лоты</a></div>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php
define('INTERNAL',1);
require_once('../login/code.php');
if (requireLogin()) {header('Location: /index.php', 1, 301); exit;}
header('Content-Type: text/html;charset=utf-8');
$right = $rights[$user['rights']];
$method = $_SERVER['REQUEST_METHOD'];
require_once('../../config.php');
if ($method == 'POST'){ processPost(); exit; }
$act = '';
if (isset($_GET['act'])) $act = $_GET['act'];
if (in_array($act, array('create', 'edit', 'delete', 'view'))){
require_once('$act.php'); exit;
}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT lots.id, lots.name, lots.images, lots.organizer,
cat.name AS category, users.firstname, users.lastname
FROM lots, categories cat, users
WHERE cat.id=lots.category AND users.id=lots.organizer ORDER BY lots.id LIMIT 0,30';
$result = mysqli_query($dblink, $query);
$keys = array('name', 'category', 'images', 'description', 'lottype', 'auctiontype',
'cost','step','startdate', 'enddate');
$keys = array('id', 'name', 'category', 'images', 'organizer');
$thead = ''; $tbody = '';
$labels = array('id', 'Название', 'Категория', 'Изображение', 'Организатор');
foreach ($labels as $key){
$thead .= '<th>$key</th>';
}
for ($i=0;$i<$result->num_rows;$i++){
$record = $result->fetch_assoc();
$idd = $record['id'];
$tbody .= '<tr align='center'>';
foreach ($keys as $key){
$value = $record[$key];
if ($key == 'name') $tbody .= '<td><a href='?act=view&id=$idd'>$value</a></td>';
elseif ($key == 'images' && $value != ''){
$imgs = explode(';',$value);
$img = $imgs[0];
$tbody .= '<td><img src='/images/data/$img[0]$img[1]/$img[2]$img[3]/$img' width='100' height='100'/></td>';
}elseif($key == 'organizer'){
$tbody .= '<td><a href='/mod/users?act=view&id=$value'>$record[firstname] $record[lastname]</a></td>';
}
else $tbody .= '<td>$value</td>';
}
$tbody .= '</tr>';
}
$result->free_result();
mysqli_close($dblink);
$output = true;
if ($output):
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='init();'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Лоты</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content'>
<div align='center'><table>
<thead><tr><?php echo $thead; ?></tr></thead>
<tbody><?php echo $tbody; ?></tbody>
</table></div>
<div align='center' style='width : 100%;padding-top: 15px' ><a href='?act=create'>Создать лот</a></div>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php endif;
function processPost(){
global $config;
if (!isset($_POST['act'])) return;
$act = $_POST['act'];
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$args = array('db'=>$dblink);
if ($act == 'create') createLot($args);
if ($act == 'update') updateLot($args);
mysqli_close($dblink);
}
function createLot($args){
$dblink = $args['db'];
$keys = array('name', 'category', 'description', 'lottype', 'auctiontype',
'cost','step', 'startdate', 'enddate');
foreach ($keys as $key){
if (!isset($_POST[$key])){ return;}
}
$images = $_FILES['images'];
$types = array('image/jpeg'=>'jpg', 'image/png'=>'png');
$data = $_POST;
$data['images'] = array();
$data['cost'] = str_replace(' ', '', $data['cost']);
$data['step'] = str_replace(' ', '', $data['step']);
if (!preg_match('/^[0-9]+(.[0-9]+){0,1}$/', $data['cost']) ||
!preg_match('/^[0-9]+$/', $data['category'])) {
header('Location: index.php?act=create', true, 301); return;
}
if ($data['lottype'] == 'auction' &&
!preg_match('/^[0-9]+(.[0-9]+){0,1}$/', $data['step'])){
header('Location: index.php?act=create', true, 301); return;
}
$datetime = createDateTime($data['startdate']);
if ($datetime) $data['startdate'] = $datetime->getTimestamp();
else $data['startdate'] = 0;
$datetime = createDateTime($data['enddate']);
if ($datetime) $data['enddate'] = $datetime->getTimestamp();
else $data['enddate'] = 0;
for($i=0;$i<count($images['name']);$i++){
if ($images['name'][$i] == '') break;
$hash = sha1_file($images['tmp_name'][$i]);
$dir = 'images/data/$hash[0]$hash[1]/$hash[2]$hash[3]';
$path = '$dir/$hash';
$info = getimagesize($images['tmp_name'][$i]);
$type = $types[$info['mime']];
if ($type != 'jpg' && $type != 'png'){
header('Location: index.php?act=create', true, 301); return;
}
$data['images'][] = '$hash.$type';
$root = dirname(dirname(dirname(__FILE__)));
if (!file_exists('$root/$dir')) mkdir('$root/$dir', 0777, true);
move_uploaded_file($images['tmp_name'][$i], '$root/$path.$type');
}
$data['images'] = implode(';', $data['images']);
$keys[] = 'images';
$data['organizer'] = $_SESSION['user']['id'];
$keys[] = 'organizer';
$fields = array();
$vals = array();
foreach ($keys as $key){
$fields[] = '`$key`';
$vals[] = '''.mysqli_real_escape_string($dblink, $data[$key]).''';
}
$fields = implode(', ', $fields);
$vals = implode(', ', $vals);
$query = 'INSERT INTO lots ($fields) VALUES($vals)';
mysqli_query($dblink, $query);
header('Location: index.php', true, 301);
}
function updateLot($args){
$dblink = $args['db'];
if (!isset($_POST['id']) || !preg_match('/^[0-9]+$/', $_POST['id'])){ return; }
$id = $_POST['id'];
$keys = array('name', 'category', 'description', 'lottype', 'auctiontype',
'cost','step', 'startdate', 'enddate');
foreach ($keys as $key){
if (!isset($_POST[$key])){ return;}
}
$images = $_FILES['images'];
$types = array('image/jpeg'=>'jpg', 'image/png'=>'png');
$data = $_POST;
$data['images'] = array();
$data['cost'] = str_replace(' ', '', $data['cost']);
$data['step'] = str_replace(' ', '', $data['step']);
if (!preg_match('/^[0-9]+(.[0-9]+){0,1}$/', $data['cost']) ||
!preg_match('/^[0-9]+$/', $data['category'])) {
header('Location: index.php?act=edit&id=$id', true, 301); return;
}
if ($data['lottype'] == 'auction' &&
!preg_match('/^[0-9]+(.[0-9]+){0,1}$/', $data['step'])){
header('Location: index.php?act=edit&id=$id', true, 301); return;
}
$datetime = createDateTime($data['startdate']);
if ($datetime) $data['startdate'] = $datetime->getTimestamp();
else $data['startdate'] = 0;
$datetime = createDateTime($data['enddate']);
if ($datetime) $data['enddate'] = $datetime->getTimestamp();
else $data['enddate'] = 0;
for($i=0;$i<count($images['name']);$i++){
if ($images['name'][$i] == '') break;
$hash = sha1_file($images['tmp_name'][$i]);
$dir = 'images/data/$hash[0]$hash[1]/$hash[2]$hash[3]';
$path = '$dir/$hash';
$info = getimagesize($images['tmp_name'][$i]);
$type = $types[$info['mime']];
if ($type != 'jpg' && $type != 'png'){
header('Location: index.php?act=edit&id=$id', true, 301);
return;
}
$data['images'][] = '$hash.$type';
$root = dirname(dirname(dirname(__FILE__)));
if (!file_exists('$root/$dir')) mkdir('$root/$dir', 0777, true);
move_uploaded_file($images['tmp_name'][$i], '$root/$path.$type');
}
$data['images'] = implode(';', $data['images']);
if ($data['images'] != '') $keys[] = 'images';
$fields = array();
foreach ($keys as $key){
$fields[] = '`$key`=''.mysqli_real_escape_string($dblink, $data[$key]).''';
}
$fields = implode(', ', $fields);
$query = 'UPDATE lots SET $fields WHERE id=$id';
mysqli_query($dblink, $query);
header('Location: index.php', true, 301);
}
function createDateTime($str){
$parts = preg_split('/s+/', $str);
$format = '';
if (!isset($parts[0])) return false;
$parts1 = explode('.', $parts[0]);
if (isset($parts1[0])) $format .= 'd';
if (isset($parts1[1])) $format .= '.m';
if (isset($parts1[2])) $format .= '.Y';
if (!isset($parts[1])) return DateTime::createFromFormat($format, $str);
$parts1 = explode(':', $parts[1]);
if (isset($parts1[0])) $format .= ' H';
if (isset($parts1[1])) $format .= ':i';
if (isset($parts1[2])) $format .= ':s';
return DateTime::createFromFormat($format, $str);
}
?>
<?php
defined('INTERNAL') or die();
$current = $_SESSION['user'];
$id = '';
if (!isset($_GET['id'])) {
header('Location: index.php', true, 301);
exit;
}
$id = $_GET['id'];
if (!preg_match('/^[0-9]+$/', $id)) {
header('Location: index.php', true, 301);
exit;
}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT id FROM `order` WHERE lot=$id';
$result = mysqli_query($dblink, $query);
$row = $result->fetch_assoc();
$result->free_result();
$selt = $row?true:false;
$query = 'SELECT lots.id, lots.organizer, lots.name, lots.images,
lots.description, lots.auctiontype, lots.lottype,
lots.startdate, lots.enddate, lots.cost, lots.step, cat.name AS category
FROM lots, categories cat WHERE lots.id=$id AND cat.id=lots.category';
$result = mysqli_query($dblink, $query);
//echo mysqli_error($dblink);
$record = $result->fetch_assoc();
$result->free();
$customers = ''; $islotorganizer = false;
if ($current['id'] == $record['organizer']) $islotorganizer = true;
$query = 'SELECT v.id, v.cost, v.user, u.firstname, u.lastname
FROM ventures v, users u
WHERE v.lot=$record[id] AND u.id=v.user';
$result = mysqli_query($dblink, $query);
while($row = $result->fetch_assoc()){
if ($row['user'] == $current['id']) continue;
$customers .= '<option value='$row[id]'>$row[firstname] $row[lastname], $row[cost]</option>';;
}
$result->free();
mysqli_close($dblink);
if (!$record) {
header('Location: index.php', true, 301);
exit;
}
$lottype = $record['lottype'];
if ($record['lottype'] == 'fixed')
$record['lottype'] = 'Фиксированная цена';
else
$record['lottype'] = 'Аукцион';
if ($record['auctiontype'] == 'public')
$record['auctiontype'] = 'Открытый';
else
$record['auctiontype'] = 'Закрытый';
if ($record['startdate'] == '0') $record['startdate'] = '-';
else $record['startdate'] = date('d.m.Y H:i:s', (int)$record['startdate']);
if ($record['enddate'] == '0') $record['enddate'] = '-';
else $record['enddate'] = date('d.m.Y H:i:s', (int)$record['enddate']);
$record['cost'] = number_format((float)$record['cost'], 3, '.', '');
$record['step'] = number_format((float)$record['step'], 3, '.', '');
$images = $record['images'] = explode(';', $record['images']);
$image = $images[0];
if ($image != '') $image = '/images/data/$image[0]$image[1]/$image[2]$image[3]/$image';
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='viewlot.init();game.init();'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Просмотр лота</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form id='view' action='index.php' method='post' enctype='multipart/form-data'>
<table>
<thead><tr><th width='20%'></th><th width='40%'></th></tr></thead>
<tbody>
<tr><td>Название лота</td><td><?php echo $record['name']; ?></td></tr>
<tr><td>Категория лота</td><td><?php echo $record['category']; ?></td></tr>
<tr><td>Описание лота</td><td><?php echo $record['description']; ?></td></tr>
<tr><td>Тип лота</td><td><?php echo $record['lottype']; ?></td></tr>
<tr><td>Тип аукциона</td><td><?php echo $record['auctiontype']; ?></td></tr>
<tr><td>Цена объекта</td><td><?php echo $record['cost']; ?></td></tr>
<tr><td><a href='/mod/messages/?lot=<?php echo $id?>'>Переписка по лоту</a></td></tr>
<?php if (!$selt):?>
<?php if ($lottype == 'auction'):?>
<tr><td>Шаг торгов</td><td><?php echo $record['step']; ?></td></tr>
<?php endif; ?>
<tr><td>Начало торгов</td><td><?php echo $record['startdate']; ?></td></tr>
<tr><td>Конец торгов</td><td><?php echo $record['enddate']; ?></td></tr>
<?php if ($islotorganizer):?>
<tr><td>Покупатели</td><td><select name='customer'><?php echo $customers; ?></select></td></tr>
<tr><td><button name='sale'>Продать</button></td></tr>
<?php endif;?>
<?php if ($lottype == 'fixed' && !$islotorganizer):?>
<tr><td><button name='buy'>Хочу купить</button></td></tr>
<?php endif;?>
<?php if ($lottype == 'auction' && !$islotorganizer):?>
<tr><td><button name='inc'>+</button><button name='dec'>-</button></td></tr>
<tr><td><input type='text' name='cost' size='20' maxlength='20' /></td><td><button name='setcost'>Предложить цену</button></td></tr>
<?php endif; endif;?>
<?php if ($selt): ?>
<tr><td><b>Продано</b></td></tr>
<?php endif; if ($image != ''): ?>
<tr><td><img name='picture' width='200' height='200' src='<?php echo $image; ?>' /></td></tr>
<?php endif;?>
<tr><td>
<?php
if ($image != '') {
foreach ($images as $image):
if ($image != '') {
$image = '/images/data/$image[0]$image[1]/$image[2]$image[3]/$image';
}
?>
<input type='radio' name='images' value='<?php echo $image; ?>' />
<?php endforeach;
}
?>
</td></tr>
</tbody></table>
<input type='hidden' name='lotid' value='<?php echo $record['id']; ?>' />
</form>
<?php if (!$selt): ?>
<div><a href='index.php?act=edit&id=<?php echo $record['id']; ?>'>Редактировать</a></div><?php endif;?>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
ПРИЛОЖЕНИЕ Г
Модули PHP работы с пользователями
<?php
defined('INTERNAL') or die();
$current = $_SESSION['user'];
$id = '';
if (!isset($_GET['id'])) {
header('Location: index.php', true, 301);
exit;
}
$id = $_GET['id'];
if (!preg_match('/^[0-9]+$/', $id)) {
header('Location: index.php', true, 301);
exit;
}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT id FROM `order` WHERE lot=$id';
$result = mysqli_query($dblink, $query);
$row = $result->fetch_assoc();
$result->free_result();
$selt = $row?true:false;
$query = 'SELECT lots.id, lots.organizer, lots.name, lots.images,
lots.description, lots.auctiontype, lots.lottype,
lots.startdate, lots.enddate, lots.cost, lots.step, cat.name AS category
FROM lots, categories cat WHERE lots.id=$id AND cat.id=lots.category';
$result = mysqli_query($dblink, $query);
//echo mysqli_error($dblink);
$record = $result->fetch_assoc();
$result->free();
$customers = ''; $islotorganizer = false;
if ($current['id'] == $record['organizer']) $islotorganizer = true;
$query = 'SELECT v.id, v.cost, v.user, u.firstname, u.lastname
FROM ventures v, users u
WHERE v.lot=$record[id] AND u.id=v.user';
$result = mysqli_query($dblink, $query);
while($row = $result->fetch_assoc()){
if ($row['user'] == $current['id']) continue;
$customers .= '<option value='$row[id]'>$row[firstname] $row[lastname], $row[cost]</option>';;
}
$result->free();
mysqli_close($dblink);
if (!$record) {
header('Location: index.php', true, 301);
exit;
}
$lottype = $record['lottype'];
if ($record['lottype'] == 'fixed')
$record['lottype'] = 'Фиксированная цена';
else
$record['lottype'] = 'Аукцион';
if ($record['auctiontype'] == 'public')
$record['auctiontype'] = 'Открытый';
else
$record['auctiontype'] = 'Закрытый';
if ($record['startdate'] == '0') $record['startdate'] = '-';
else $record['startdate'] = date('d.m.Y H:i:s', (int)$record['startdate']);
if ($record['enddate'] == '0') $record['enddate'] = '-';
else $record['enddate'] = date('d.m.Y H:i:s', (int)$record['enddate']);
$record['cost'] = number_format((float)$record['cost'], 3, '.', '');
$record['step'] = number_format((float)$record['step'], 3, '.', '');
$images = $record['images'] = explode(';', $record['images']);
$image = $images[0];
if ($image != '') $image = '/images/data/$image[0]$image[1]/$image[2]$image[3]/$image';
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='viewlot.init();game.init();'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Просмотр лота</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form id='view' action='index.php' method='post' enctype='multipart/form-data'>
<table>
<thead><tr><th width='20%'></th><th width='40%'></th></tr></thead>
<tbody>
<tr><td>Название лота</td><td><?php echo $record['name']; ?></td></tr>
<tr><td>Категория лота</td><td><?php echo $record['category']; ?></td></tr>
<tr><td>Описание лота</td><td><?php echo $record['description']; ?></td></tr>
<tr><td>Тип лота</td><td><?php echo $record['lottype']; ?></td></tr>
<tr><td>Тип аукциона</td><td><?php echo $record['auctiontype']; ?></td></tr>
<tr><td>Цена объекта</td><td><?php echo $record['cost']; ?></td></tr>
<tr><td><a href='/mod/messages/?lot=<?php echo $id?>'>Переписка по лоту</a></td></tr>
<?php if (!$selt):?>
<?php if ($lottype == 'auction'):?>
<tr><td>Шаг торгов</td><td><?php echo $record['step']; ?></td></tr>
<?php endif; ?>
<tr><td>Начало торгов</td><td><?php echo $record['startdate']; ?></td></tr>
<tr><td>Конец торгов</td><td><?php echo $record['enddate']; ?></td></tr>
<?php if ($islotorganizer):?>
<tr><td>Покупатели</td><td><select name='customer'><?php echo $customers; ?></select></td></tr>
<tr><td><button name='sale'>Продать</button></td></tr>
<?php endif;?>
<?php if ($lottype == 'fixed' && !$islotorganizer):?>
<tr><td><button name='buy'>Хочу купить</button></td></tr>
<?php endif;?>
<?php if ($lottype == 'auction' && !$islotorganizer):?>
<tr><td><button name='inc'>+</button><button name='dec'>-</button></td></tr>
<tr><td><input type='text' name='cost' size='20' maxlength='20' /></td><td><button name='setcost'>Предложить цену</button></td></tr>
<?php endif; endif;?>
<?php if ($selt): ?>
<tr><td><b>Продано</b></td></tr>
<?php endif; if ($image != ''): ?>
<tr><td><img name='picture' width='200' height='200' src='<?php echo $image; ?>' /></td></tr>
<?php endif;?>
<tr><td>
<?php
if ($image != '') {
foreach ($images as $image):
if ($image != '') {
$image = '/images/data/$image[0]$image[1]/$image[2]$image[3]/$image';
}
?>
<input type='radio' name='images' value='<?php echo $image; ?>' />
<?php endforeach;
}
?>
</td></tr>
</tbody></table>
<input type='hidden' name='lotid' value='<?php echo $record['id']; ?>' />
</form>
<?php if (!$selt): ?>
<div><a href='index.php?act=edit&id=<?php echo $record['id']; ?>'>Редактировать</a></div><?php endif;?>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php
defined('INTERNAL') or die();
$id = '';
$current = $_SESSION['user'];
if ($current['rights'] != 'admin' || !isset($_GET['id']) ||
!preg_match('/^[0-9]+$/', $_GET['id'])){
header('Location: index.php'); exit;
}
$id = $_GET['id'];
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT * FROM users WHERE id=$id';
$result = mysqli_query($dblink, $query);
if ($result->num_rows == 0) {
$result->free_result(); mysqli_close($dblink);
header('Location: index.php'); exit;
}
$record = $result->fetch_assoc();
$keys = array('id', 'login', 'password', 'email',
'lastname', 'firstname', 'patronymic',
'rights', 'activated', 'regdate', 'blocked', 'blockend');
$rights = array('admin', 'moder', 'editor', 'user');
$select = '<select name='rights'>';
foreach ($rights as $right) $select .= '<option value='$right'>$right</option>';
$select.='</select>';
$errors = array();
$classes = array();
$vals = array();
if (isset($_SESSION['errors'])) {
$errors = $_SESSION['errors']; $vals = $errors['vals'];
unset($_SESSION['errors']);
}
if(isset($errors['password'])) $classes['password'] = 'error';
if(isset($errors['email'])) $classes['email'] = 'error';
if(isset($errors['lastname'])) $classes['lastname'] = 'error';
if(isset($errors['firstname'])) $classes['firstname'] = 'error';
if(isset($errors['patronymic'])) $classes['patronymic'] = 'error';
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='edituser.init()'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Редактирование профиля пользователя</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form action='index.php' method='post' enctype='application/x-www-form-urlencoded' id='edit-user'>
<table>
<thead><tr><th width='30%'></th><th width='70%'></th></tr></thead>
<tbody>
<tr><td>Id</td><td><?php echo $record['id']; ?></td></tr>
<tr><td>login</td><td><?php echo $record['login']; ?></td></tr>
<tr><td>Пароль</td><td><input class='<?php echo $classes['password']; ?>' type='password' size='40' maxlength='40' name='password' /><?php echo $errors['password']; ?></td></tr>
<tr><td>email</td><td><input class='<?php echo $classes['email']; ?>' type='text' size='40' maxlength='40' name='email' value='<?php echo isset($vals['email'])?$vals['email']:$record['email']; ?>' /><?php echo $errors['email']; ?></td></tr>
<tr><td>Фамилия</td><td><input class='<?php echo $classes['lastname']; ?>' type='text' size='40' maxlength='40' name='lastname' value='<?php echo $record['lastname']; ?>' /><?php echo $errors['lastname']; ?></td></tr>
<tr><td>Имя</td><td><input class='<?php echo $classes['firstname']; ?>' type='text' size='40' maxlength='40' name='firstname' value='<?php echo $record['firstname']; ?>' /><?php echo $errors['firstname']; ?></td></tr>
<tr><td>Отчество</td><td><input class='<?php echo $classes['patronymic']; ?>' type='text' size='40' maxlength='40' name='patronymic' value='<?php echo $record['patronymic']; ?>' /><?php echo $errors['patronymic']; ?></td></tr>
<tr><td>Права</td><td><?php echo $select; ?></td></tr>
</tbody></table>
<div id='search' style='width : 10%'><a href='<?php echo '?view=users&activate=1&id=$id'; ?>'>Активировать</a>
</div>
<div id='search' style='width : 10%'><a href='<?php echo '?view=users&block=1&id=$id'; ?>'>Заблокировать</a>
</div>
<input type='hidden' name='id' value='<?echo $record['id']; ?>'/>
<input type='hidden' name='act' value='save' />
<div id='search' style='width : 100%;padding-top : 15px;'><input type='submit' value='Сохранить' />
</div>
</form>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php endif;
function processPost(){
//require_once('../../config.php');
global $config;
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$args = array('db'=>$dblink);
if (isset($_POST['act'])) $act = $_POST['act'];
if ($act == 'save') saveUser($args);
if ($act == 'create') createUser($args);
mysqli_close($dblink);
}
function processUser($args){
if (isset($_POST['act'])) $act = $_POST['act'];
if ($act == 'save') saveUser($args);
if ($act == 'create') createUser($args);
}
function saveUser($args){
$dblink = $args['db'];
$errors = array();
$current = $_SESSION['user'];
if ($current['rights'] != 'admin') return;
$vals = array();
for (;;){
if (!isset($_POST['id']) || !isset($_POST['password']) ||
!isset($_POST['email']) || !isset($_POST['lastname']) ||
!isset($_POST['firstname']) || !isset($_POST['patronymic']) ||
!isset($_POST['rights'])){$errors['vars'] = 'bad POST request'; break; }
$id = $_POST['id']; $password = $_POST['password'];
$email = $_POST['email']; $lastname = $_POST['lastname'];
$firstname = $_POST['firstname']; $patronymic = $_POST['patronymic'];
$rights = $_POST['rights'];
$vals = $_POST;
if (!preg_match('/^[0-9]+$/', $id)){$errors['id']='bad id format'; break; }
if ($password != '' && !preg_match('/^[x20-x7f]{4,12}$/', $password))
{$errors['password']='bad password format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $lastname))
{$errors['lastname']='bad last name format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $firstname))
{$errors['firstname']='bad first name format'; break; }
if ($patronymic != '' && !preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $patronymic))
{$errors['patronymic']='bad patronymic format'; break; }
if (!preg_match('/^[a-z0-9-._]+@[a-z0-9-._]+$/', $email))
{$errors['email']='bad email format'; break; }
if (!in_array($rights, array('admin', 'moder', 'editor', 'user')))
{$errors['rights']='illegal rights value'; break; }
$parts = explode('@', $email);
if (!preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $parts[0]))
{$errors['email']='bad email format'; break; }
if (!preg_match('/^([a-z0-9]+([-_]{1}[a-z0-9]+){0,1}.){1,2}[a-z0-9]{2,6}$/', $parts[1]))
{$errors['email']='bad email format'; break; }
break;
}
if (count($errors)){
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=edit&id=$id', true, 301);
return;
}
if ($password!='') $password = sha1($password);
if ($password!='') $password = ' password='$password',';
else $password = ' ';
$query = 'UPDATE users SET$password email='$email',
lastname='$lastname', firstname='$firstname', patronymic='$patronymic',
rights='$rights' WHERE id=$id';
mysqli_query($dblink, $query);
$errno = mysqli_errno($dblink);
$error = mysqli_error($dblink);
//echo $errno;
if ($errno == 1062){
$key = stristr($error, ' key ');
$key = substr($key, 5);
$key = trim($key, ''');
$errors[$key] = $errors[$key] = 'На указанный $key уже зарегистрирована учётная запись';
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=edit&id=$id', true, 301);
return;
}
header('Location: index.php', true, 301);
}
function createUser($args){
$dblink = $args['db'];
$errors = array();
$current = $_SESSION['user'];
if ($current['rights'] != 'admin') return;
$vals = array();
for (;;){
if (!isset($_POST['login']) || !isset($_POST['password']) ||
!isset($_POST['email']) || !isset($_POST['lastname']) ||
!isset($_POST['firstname']) || !isset($_POST['patronymic']) ||
!isset($_POST['rights'])){$errors['vars'] = 'bad POST request'; break; }
$vals = $_POST;
$login = $_POST['login']; $password = $_POST['password'];
$email = $_POST['email']; $lastname = $_POST['lastname'];
$firstname = $_POST['firstname']; $patronymic = $_POST['patronymic'];
$rights = $_POST['rights'];
if (strlen($login)<5 || !preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $login))
{$errors['login']='bad login format'; break; }
if (!preg_match('/^[x20-x7f]{4,12}$/', $password))
{$errors['password']='bad password format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $lastname))
{$errors['lastname']='bad last name format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $firstname))
{$errors['firstname']='bad first name format'; break; }
if ($patronymic != '' && !preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $patronymic))
{$errors['patronymic']='bad patronymic format'; break; }
if (!preg_match('/^[a-z0-9-._]+@[a-z0-9-._]+$/', $email))
{$errors['email']='bad email format'; break; }
if (!in_array($rights, array('admin', 'moder', 'editor', 'user')))
{$errors['rights']='illegal rights value'; break; }
$parts = explode('@', $email);
if (!preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $parts[0]))
{$errors['email']='bad email format'; break; }
if (!preg_match('/^([a-z0-9]+([-_]{1}[a-z0-9]+){0,1}.){1,2}[a-z0-9]{2,6}$/', $parts[1]))
{$errors['email']='bad email format'; break; }
break;
}
if (count($errors)){
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=create', true, 301);
return;
}
$password = sha1($password);
$regdate = time();
$query = 'INSERT INTO users (login, password, email, lastname, firstname, patronymic, rights, regdate, activated)
VALUES('$login', '$password', '$email', '$lastname', '$firstname', '$patronymic', '$rights', $regdate, 1)';
mysqli_query($dblink, $query);
$errno = mysqli_errno($dblink);
$error = mysqli_error($dblink);
if ($errno == 1062){
$key = stristr($error, ' key ');
$key = substr($key, 5);
$key = trim($key, ''');
$errors[$key] = 'На указанный $key уже зарегистрирована учётная запись';
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=create', true, 301);
return;
}
header('Location: index.php', true, 301);
}
?>
<?php
define('INTERNAL',1);
require_once('../login/code.php');
if (requireLogin()) {header('Location: /index.php', 1, 301); exit;}
header('Content-Type: text/html;charset=utf-8');
$user = $_SESSION['user'];
$rights = array('user'=>1,'editor'=>2,'moder'=>3,'admin'=>4);
$right = $rights[$user['rights']];
$method = $_SERVER['REQUEST_METHOD'];
require_once('../../config.php');
if ($method == 'POST'){ processPost(); exit; }
if (isset($_GET['act']) ){
$act = $_GET['act'];
if (in_array($act, array('edit', 'create', 'view'))){require_once('$act.php'); exit;}
header('Location: index.php', 1, 301); exit;
}
if ($right<3){header('Location: /mod/admin/index.php', 1, 301); exit;}
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT * FROM users LIMIT 0,30';
$result = mysqli_query($dblink, $query);
$keys = array('id', 'login', 'email',
'lastname', 'firstname', 'patronymic',
'rights', 'activated', 'regdate', 'token',
'blocked', 'blockend');
$keys = array('id', 'login', 'email',
'lastname', 'firstname', 'patronymic',
'rights', 'activated', 'regdate');
$thead = '';
$tbody = '';
$labels = array('id', 'Логин', 'email',
'Фамилия', 'Имя', 'Отчество',
'Права', 'Активирован', 'Дата регистрации', 'Токен',
'Заблокирован', 'Окончание блокировки');
$labels = array('id', 'Логин', 'email',
'Фамилия', 'Имя', 'Отчество',
'Права', 'Активирован', 'Дата регистрации');
foreach ($labels as $key){
$thead .= '<th>$key</th>';
}
for ($i=0;$i<$result->num_rows;$i++){
$record = $result->fetch_assoc();
$tbody .= '<tr align='center'>';
foreach ($keys as $key){
$value = $record[$key];
if ($key == 'id') $tbody .= '<td><a href='?act=view&id=$value'>$value</a></td>';
elseif ($key == 'regdate') $tbody .= '<td>'.date('d.m.Y H:i:s', $value).'</td>';
else $tbody .= '<td>$value</td>';
}
$tbody .= '</tr>';
}
$result->free_result();
mysqli_close($dblink);
header('Content-Type: text/html;charset=utf-8');
$output = true;
if ($output):
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='init();'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Пользователи</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content'>
<table style='font-size : 10pt;' class='table table-striped'>
<thead><tr><?php echo $thead; ?>
</tr></thead>
<tbody ><?php echo $tbody; ?></tbody>
</table>
<a href='?act=create'>Создать</a>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php endif;
function processPost(){
//require_once('../../config.php');
global $config;
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$args = array('db'=>$dblink);
if (isset($_POST['act'])) $act = $_POST['act'];
if ($act == 'save') saveUser($args);
if ($act == 'create') createUser($args);
mysqli_close($dblink);
}
function processUser($args){
if (isset($_POST['act'])) $act = $_POST['act'];
if ($act == 'save') saveUser($args);
if ($act == 'create') createUser($args);
}
function saveUser($args){
$dblink = $args['db'];
$errors = array();
$current = $_SESSION['user'];
if ($current['rights'] != 'admin') return;
$vals = array();
for (;;){
if (!isset($_POST['id']) || !isset($_POST['password']) ||
!isset($_POST['email']) || !isset($_POST['lastname']) ||
!isset($_POST['firstname']) || !isset($_POST['patronymic']) ||
!isset($_POST['rights'])){$errors['vars'] = 'bad POST request'; break; }
$id = $_POST['id']; $password = $_POST['password'];
$email = $_POST['email']; $lastname = $_POST['lastname'];
$firstname = $_POST['firstname']; $patronymic = $_POST['patronymic'];
$rights = $_POST['rights'];
$vals = $_POST;
if (!preg_match('/^[0-9]+$/', $id)){$errors['id']='bad id format'; break; }
if ($password != '' && !preg_match('/^[x20-x7f]{4,12}$/', $password))
{$errors['password']='bad password format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $lastname))
{$errors['lastname']='bad last name format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $firstname))
{$errors['firstname']='bad first name format'; break; }
if ($patronymic != '' && !preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $patronymic))
{$errors['patronymic']='bad patronymic format'; break; }
if (!preg_match('/^[a-z0-9-._]+@[a-z0-9-._]+$/', $email))
{$errors['email']='bad email format'; break; }
if (!in_array($rights, array('admin', 'moder', 'editor', 'user')))
{$errors['rights']='illegal rights value'; break; }
$parts = explode('@', $email);
if (!preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $parts[0]))
{$errors['email']='bad email format'; break; }
if (!preg_match('/^([a-z0-9]+([-_]{1}[a-z0-9]+){0,1}.){1,2}[a-z0-9]{2,6}$/', $parts[1]))
{$errors['email']='bad email format'; break; }
break;
}
if (count($errors)){
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=edit&id=$id', true, 301);
return;
}
if ($password!='') $password = sha1($password);
if ($password!='') $password = ' password='$password',';
else $password = ' ';
$query = 'UPDATE users SET$password email='$email',
lastname='$lastname', firstname='$firstname', patronymic='$patronymic',
rights='$rights' WHERE id=$id';
mysqli_query($dblink, $query);
$errno = mysqli_errno($dblink);
$error = mysqli_error($dblink);
//echo $errno;
if ($errno == 1062){
$key = stristr($error, ' key ');
$key = substr($key, 5);
$key = trim($key, ''');
$errors[$key] = $errors[$key] = 'На указанный $key уже зарегистрирована учётная запись';
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=edit&id=$id', true, 301);
return;
}
header('Location: index.php', true, 301);
}
function createUser($args){
$dblink = $args['db'];
$errors = array();
$current = $_SESSION['user'];
if ($current['rights'] != 'admin') return;
$vals = array();
for (;;){
if (!isset($_POST['login']) || !isset($_POST['password']) ||
!isset($_POST['email']) || !isset($_POST['lastname']) ||
!isset($_POST['firstname']) || !isset($_POST['patronymic']) ||
!isset($_POST['rights'])){$errors['vars'] = 'bad POST request'; break; }
$vals = $_POST;
$login = $_POST['login']; $password = $_POST['password'];
$email = $_POST['email']; $lastname = $_POST['lastname'];
$firstname = $_POST['firstname']; $patronymic = $_POST['patronymic'];
$rights = $_POST['rights'];
if (strlen($login)<5 || !preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $login))
{$errors['login']='bad login format'; break; }
if (!preg_match('/^[x20-x7f]{4,12}$/', $password))
{$errors['password']='bad password format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $lastname))
{$errors['lastname']='bad last name format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $firstname))
{$errors['firstname']='bad first name format'; break; }
if ($patronymic != '' && !preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $patronymic))
{$errors['patronymic']='bad patronymic format'; break; }
if (!preg_match('/^[a-z0-9-._]+@[a-z0-9-._]+$/', $email))
{$errors['email']='bad email format'; break; }
if (!in_array($rights, array('admin', 'moder', 'editor', 'user')))
{$errors['rights']='illegal rights value'; break; }
$parts = explode('@', $email);
if (!preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $parts[0]))
{$errors['email']='bad email format'; break; }
if (!preg_match('/^([a-z0-9]+([-_]{1}[a-z0-9]+){0,1}.){1,2}[a-z0-9]{2,6}$/', $parts[1]))
{$errors['email']='bad email format'; break; }
break;
}
if (count($errors)){
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=create', true, 301);
return;
}
$password = sha1($password);
$regdate = time();
$query = 'INSERT INTO users (login, password, email, lastname, firstname, patronymic, rights, regdate, activated)
VALUES('$login', '$password', '$email', '$lastname', '$firstname', '$patronymic', '$rights', $regdate, 1)';
mysqli_query($dblink, $query);
$errno = mysqli_errno($dblink);
$error = mysqli_error($dblink);
if ($errno == 1062){
$key = stristr($error, ' key ');
$key = substr($key, 5);
$key = trim($key, ''');
$errors[$key] = 'На указанный $key уже зарегистрирована учётная запись';
$_SESSION['errors'] = $errors;
$_SESSION['errors']['vals'] = $vals;
header('Location: ?act=create', true, 301);
return;
}
header('Location: index.php', true, 301);
}
?>
<?php
define('INTERNAL',1);
require_once('../login/code.php');
require_once('../../config.php');
if (!requireLogin()) {header('Location: /index.php', 1, 301); exit;}
header('Content-Type: text/html;charset=utf-8');
$errors = array();
$classes = array();
$vals = array();
$method = $_SERVER['REQUEST_METHOD'];
if ($method == 'GET'){ $output = true; }
if ($method == 'POST'){
processPost($args);
if (isset($args['errors'])){
$errors = $args['errors'];
$vals = $errors['vals'];
$output = true;
}
}
if(isset($errors['login'])) $classes['login'] = 'error';
if(isset($errors['password'])) $classes['password'] = 'error';
if(isset($errors['email'])) $classes['email'] = 'error';
if(isset($errors['lastname'])) $classes['lastname'] = 'error';
if(isset($errors['firstname'])) $classes['firstname'] = 'error';
if(isset($errors['patronymic'])) $classes['patronymic'] = 'error';
if (!$output):{
header('Location: /index.php', true, 301);
}else:
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='createuser.init();'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Регистрация пользователя</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<div id='content' style='padding-left : 10px'>
<form action='register.php' method='post' enctype='application/x-www-form-urlencoded' id='create-user'>
<table>
<thead><tr><th width='30%'></th><th width='70%'></th></tr></thead>
<tbody>
<tr><td>login</td><td><input class='<?php echo $classes['login']; ?>' type='text' size='40' maxlength='40' name='login' value='<?php echo $vals['login']; ?>' /><?php echo $errors['login']; ?></td></tr>
<tr><td>Пароль</td><td><input class='<?php echo $classes['password']; ?>' type='password' size='40' maxlength='40' name='password' value='<?php echo $vals['password']; ?>' /><?php echo $errors['password']; ?></td></tr>
<tr><td>email</td><td><input class='<?php echo $classes['email']; ?>' type='text' size='40' maxlength='40' name='email' value='<?php echo $vals['email']; ?>' /><?php echo $errors['email']; ?></td></tr>
<tr><td>Фамилия</td><td><input class='<?php echo $classes['lastname']; ?>' type='text' size='40' maxlength='40' name='lastname' value='<?php echo $vals['lastname']; ?>' /><?php echo $errors['lastname']; ?></td></tr>
<tr><td>Имя</td><td><input class='<?php echo $classes['firstname']; ?>' type='text' size='40' maxlength='40' name='firstname' value='<?php echo $vals['firstname']; ?>' /><?php echo $errors['firstname']; ?></td></tr>
<tr><td>Отчество</td><td><input class='<?php echo $classes['patronymic']; ?>' type='text' size='40' maxlength='40' name='patronymic' value='<?php echo $vals['patronymic']; ?>' /><?php echo $errors['patronymic']?></td></tr>
</tbody></table>
<input type='hidden' name='act' value='create' />
<input type='submit' value='Сохранить' />
</form>
</div>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>
<?php endif;
function processPost(&$args){
global $config;
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$args['db'] = $dblink;
registerUser($args);
//var_dump($args);
mysqli_close($dblink);
unset($args['db']);
}
function registerUser(&$args){
$dblink = $args['db'];
$errors = array();
$vals = array();
for (;;){
if (!isset($_POST['login']) || !isset($_POST['password']) ||
!isset($_POST['email']) || !isset($_POST['lastname']) ||
!isset($_POST['firstname']) || !isset($_POST['patronymic']))
{$errors['vars'] = 'bad POST request'; break; }
$login = $_POST['login']; $password = $_POST['password'];
$email = $_POST['email']; $lastname = $_POST['lastname'];
$firstname = $_POST['firstname']; $patronymic = $_POST['patronymic'];
$rights = 'user';
$vals = $_POST;
if (strlen($login)<5 || !preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $login))
{$errors['login']='bad login format'; break; }
if ($password != '' && !preg_match('/^[x20-x7f]{4,12}$/', $password))
{$errors['password']='bad password format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $lastname))
{$errors['lastname']='bad last name format'; break; }
if (!preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $firstname))
{$errors['firstname']='bad first name format'; break; }
if ($patronymic != '' && !preg_match('/^([А-ЯЁ]{1}[а-яё]+|[A-Z]{1}[a-z]+)$/u', $patronymic))
{$errors['patronymic']='bad patronymic format'; break; }
if (!preg_match('/^[a-z0-9-._]+@[a-z0-9-._]+$/', $email))
{$errors['email']='bad email format'; break; }
$parts = explode('@', $email);
if (!preg_match('/^[a-z0-9]+([.-_]{1}[a-z0-9]+){0,2}$/', $parts[0]))
{$errors['email']='bad email format'; break; }
if (!preg_match('/^([a-z0-9]+([-_]{1}[a-z0-9]+){0,1}.){1,2}[a-z0-9]{2,6}$/', $parts[1]))
{$errors['email']='bad email format'; break; }
break;
}
if (count($errors)){
$errors['vals'] = $vals;
$args['errors'] = $errors;
return;
}
$password = sha1($password);
$regdate = time();
$token = rand(0, 1000000000);
$token = sha1('$token');
$query = 'INSERT INTO users (login, password, email, lastname, firstname, patronymic, rights, regdate, activated, token)
VALUES('$login', '$password', '$email', '$lastname', '$firstname', '$patronymic', '$rights', $regdate, 1, '$token')';
mysqli_query($dblink, $query);
$errno = mysqli_errno($dblink);
$error = mysqli_error($dblink);
if ($errno == 1062){
$key = stristr($error, ' key ');
$key = substr($key, 5);
$key = trim($key, ''');
$errors[$key] = $errors[$key] = 'На указанный $key уже зарегистрирована учётная запись';
$errors['vals'] = $vals;
$args['errors'] = $errors;
return;
}
$query = 'SELECT * FROM users WHERE id=$dblink->insert_id';
$result = mysqli_query($dblink, $query);
$_SESSION['user'] = $result->fetch_assoc();
$result->free();
/*require_once ('../../library/phpmailer/class.phpmailer.php');
$mailer = new PHPMailer();
$mailer->From = 'admin@'.$_SERVER['SERVER_NAME'];
$mailer->FromName = 'Администратор';
$mailer->Subject = 'Подтвердите регистрацию';
$mailer->CharSet = 'utf8';*/
}
?>
<?php
defined('INTERNAL') or die();
$id = '';
$current = $_SESSION['user'];
if ($current['rights'] != 'admin' || !isset($_GET['id']) ||
!preg_match('/^[0-9]+$/', $_GET['id'])){
header('Location: index.php'); exit;
}
$id = $_GET['id'];
$dblink = mysqli_connect($config->dbhost, $config->dbuser, $config->dbpwd, $config->dbname);
mysqli_query($dblink, 'set names utf8');
$query = 'SELECT * FROM users WHERE id=$id';
$result = mysqli_query($dblink, $query);
if ($result->num_rows == 0) {
$result->free_result(); mysqli_close($dblink);
header('Location: index.php'); exit;
}
$record = $result->fetch_assoc();
$keys = array('id', 'login', 'email',
'lastname', 'firstname', 'patronymic',
'rights', 'activated', 'regdate', 'blocked', 'blockend');
$labels = array('id', 'Логин', 'email',
'Фамилия', 'Имя', 'Отчество',
'Права', 'Активирован', 'Дата регистрации', 'Заблокирован', 'Окончание блокировки');
$tbody = '';
for ($i=0;$i<count($keys);$i++){
$key = $keys[$i];
$value = $record[$key];
if ($key == 'regdate' || $key == 'blockend'){
if ($value != '0'){
$value = date('d.m.Y H:i:s', $value);
}else $value = '-';
}
if ($key == 'activated' || $key == 'blocked'){
if ($value == '1') $value = 'Да';
if ($value == '0') $value = 'Нет';
}
$tbody .= '<tr><td>$labels[$i]</td><td>$value</td></tr>';
}
$block = array('block', 'Заблокировать');
if ($record['blocked']) $block = array('unlock', 'Разблокировать');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Your Name Here - Simple</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta name='description' content=''>
<meta name='author' content=''>
<link href='/scripts/bootstrap/css/bootstrap.min.css' rel='stylesheet'>
<link href='/scripts/bootstrap/css/bootstrap-responsive.min.css' rel='stylesheet'>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
<![endif]-->
<!-- Icons -->
<link href='/scripts/icons/general/stylesheets/general_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<link href='/scripts/icons/social/stylesheets/social_foundicons.css' media='screen' rel='stylesheet' type='text/css' />
<!--[if lt IE 8]>
<link href='scripts/icons/general/stylesheets/general_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<link href='scripts/icons/social/stylesheets/social_foundicons_ie7.css' media='screen' rel='stylesheet' type='text/css' />
<![endif]-->
<link rel='stylesheet' href='/scripts/fontawesome/css/font-awesome.min.css'>
<!--[if IE 7]>
<link rel='stylesheet' href='scripts/fontawesome/css/font-awesome-ie7.min.css'>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Palatino+Linotype' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Abel' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='/styles/custom.css' rel='stylesheet' type='text/css' />
<link rel='icon' href='logo.ico' type='image/x-icon' />
<link rel='shortcut icon' href='logo.ico' type='image/x-icon' />
<script type='text/javascript' src='/js/index.js' charset='utf-8'></script>
</head>
<body id='pageBody' onload='edituser.init()'>
<div id='decorative2'>
<div class='container'>
<div class='divPanel topArea notop nobottom'>
<div class='row-fluid'>
<div class='span12'>
<div id='divLogo' class='pull-left'>
<a href='index.html' id='divSiteTitle'>Аукцион</a><br />
<a href='index.html' id='divTagLine'> </a>
</div>
<div id='divMenuRight' class='pull-right'>
<div class='navbar'>
<button type='button' class='btn btn-navbar-highlight btn-large btn-primary' data-toggle='collapse' data-target='.nav-collapse'>
NAVIGATION <span class='icon-chevron-down icon-white'></span>
</button>
<div class='nav-collapse collapse'>
<ul class='nav nav-pills ddmenu'>
<li class='dropdown'><a href='about.php'>О нас</a></li>
<li class='dropdown'><a href='contacts.html'>Контакты</a></li>
<li class='dropdown'><a href='index.php'>Вход/Регистрация</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='contentOuterSeparator'></div>
<div class='container'>
<div class='divPanel page-content'>
<div class='breadcrumbs'>
<a href='index.html'>Главная</a> / <span>Пользователи</span>
</div>
<div class='row-fluid'>
<!--Edit Main Content Area here-->
<div class='span8' id='divMain'>
<form action='index.php' method='post' enctype='application/x-www-form-urlencoded' id='edit-user'>
<table>
<thead><tr><th width='30%'></th><th width='70%'></th></tr></thead>
<tbody><?php echo $tbody; ?></tbody></table>
<div id='search' style='width : 10%'><a href='<?php echo '?act=edit&id=$id'; ?>'>Редактировать</a>
</div>
<div id='search' style='width : 10%'><a href='<?php echo '?act=create'; ?>'>Создать</a>
</div>
<?php if ($record['activated'] == 0):?>
<div id='search' style='width : 10%'><a href='<?php echo '?act=activate&id=$id'; ?>'>Активировать</a>
</div>
<?php endif; ?>
<div id='search' style='width : 10%'><a href='<?php echo '?act=$block[0]&id=$id'; ?>'><?php echo $block[1];?></a>
</div>
<input type='hidden' name='id' value='<?php echo $record['id']; ?>'/>
<input type='hidden' name='act' value='save' />
<div id='search' style='width : 70%'><p><input type='submit' value='Сохранить' /></p>
</div>
</div>
</form>
<div id='search' style='padding-top : 30px'><a href='/mod/admin'>Выйти</a>
</div>
<!--End Main Content Area here-->
</div>
</div>
<div id='footerInnerSeparator'></div>
</div>
</div>
<div id='footerOuterSeparator'></div>
<div id='divFooter' class='footerArea'>
<div class='container'>
<div class='divPanel'>
<div class='row-fluid'>
<div class='span3' id='footerArea1'>
<h3>О компании</h3>
<p>Данный сайт принадлежит ООО 'Белаукцион', которая является в Республике Беларусь крупнейшим организатором аукционов.</p>
</div>
<div class='span3' id='footerArea4'>
<h3>Контакты</h3>
<ul id='contact-info'>
<li>
<i class='general foundicon-phone icon'></i>
<span class='field'>Телефон:</span>
<br />
8 044 7777 555
</li>
<li>
<i class='general foundicon-mail icon'></i>
<span class='field'>Email:</span>
<br />
<a href='mailto:info@yourdomain.com' title='Email'>auction@gmail.com</a>
</li>
<li>
<i class='general foundicon-home icon' style='margin-bottom:50px'></i>
<span class='field'>Адрес:</span>
<br />
г. Минск<br />
246053 ул. Кальварийская, 7<br />
</li>
</ul>
</div>
</div>
<br /><br />
<div class='row-fluid'>
<div class='span12'>
<p class='copyright'>
© 2016 ООО 'Белаукцион'. Все авторские права защищены.
</p>
</div>
</div>
<br />
</div>
</div>
</div>
<script src='/scripts/jquery.min.js' type='text/javascript'></script>
<script src='/scripts/bootstrap/js/bootstrap.min.js' type='text/javascript'></script>
<script src='/scripts/default.js' type='text/javascript'></script>
</body>
</html>