Оглавление
Глава 1. Постановка задачи
1.1 Техническое задание
1.1.1 Основание для разработки
Основанием для данной работы является задание, выданное на дипломный проект для разработки: «Программный комплекс управления сайтом с использованием “Kohana Framework”». Задание для дипломного проектирования выдано в соответствии с работами провайдера ООО «Городские информационные сети» и утверждено зам. директора по учебной работе Красногорского государственного колледжа.
1.1.2 Назначение разработки
Программный комплекс управления сайтом с использованием “Kohana Framework”». Данное программное обеспечение может использоваться на любых предприятиях в качестве шаблона “движка” с возможностями добавления и отображения материалов по иерархии пользовательского доступа.
1.1.3 Требования к программе
Программа должна:
1) Отображать категории;
2) Отображать материалы по категориям;
3) Производить регистрацию и авторизацию пользователей;
4) Отправлять Email сообщения для подтверждения регистрации;
5) Предоставлять просмотр и действия согласно уровню доступа пользователя;
6) Добавлениередактированиеудаление категорий и материалов;
7) Создание тегов к материалам;
8) Проверять введенные пользователем значения от вредоносных скриптов;
9) Анализировать количество зарегистрированных пользователей и администраторов среди них.
1.1.4 Требования к надежности
Программа должна работать с базой данных в соответствии с алгоритмом функционирования, выдавать сообщения об ошибках при неверно заданных исходных данных, поддерживать диалоговый режим в рамках предоставляемых пользователю возможностей. Программа информационно защищена от попыток внедрения вредоносного кода или взлома с целью получения несанкционированного доступа к информации методами Kohana Framework, HTMLPurifier и другими.
1.1.5 Условия эксплуатации и требования к составу и параметрам технических средств
Серверная сторона:
На компьютере-сервере должна быть установлена и настроена взаимосвязь веб-серверных программ, содержащий пакет программ:
· Apache version 2.2.17 with OpenSSL
· PHP VC6 version ThreadSafe 5.3.5
· MySQL Community Server version 5.5.x
1.1.5.1 Краткие сведения по установке - Apache
1) Установка в режиме Typical
2) В файле конфигурации(httpd.conf) изменить.
<directory “c:/…/cgi-bin”>
…
</directory>
// Вставить под это пусть к каталогу сайта
<directory “c:/site”>
AllowOveride All
Options Indexes FollowSymLinks
Order allow,deny
Allow From all
</directory>
3) Снять знак комментария (#) со строчки
Include conflextra/httpd-vhosts.conf
4) Найти строку с “index.html” и добавить через пробел “ index.php”
5) Раскомментировать строку “LoadModule rewrite_module modules/mod_rewrite.so”
6) В конце файла указать пусть к файлу конфигурации PHP
PHPiniDir “c:/Program Files/php”
LoadModule php5_module “c:/Program Files/php/php5apache2_2.dll”
7) Перейти в файл httpd-vhosts.conf на редактирование, стереть все конфигурации <virtualhost>…</virtualhost> и записать новые
<virtualhost *:80>
ServerAdmin skutorlike@mail.ru
DocumentRoot “c:/site/sitename”
ServerName localhost (или sitename) // доменное имя для браузера
ServerAlias www.localhost (или www.sitename) // синоним доменного имени
ErrorLog “c:/site/localhost(sitename)/error.log”
CustomLog “c:/site/localhost(sitename)/access.log” common
</virtualhost>
1.1.5.2 Краткие сведения по установке - PHP
1) Установка по умолчанию, выбор Apache 2.2.x, указание пути конфигурационного файла Apache, Extension -> все модули
2) Настройка файла конфигурации PHP (php.ini)
Закомментировать модули:
Php_intl.dll
Php_oci8
Php_oci8_11g
Php_pdo_oci
Php_pgsql
Php_pdo_pgsql
Php_sybase_ct
3) Раскомментировать модуль работы сокращенных тегов
Short_open_tag = off // и поменять значение на on
1.1.5.3 Краткие сведения по установке - MySQL
1) Установка по умолчанию
1.1.5.4 Краткие сведения по настройке системного - hosts.conf
1) В папке Windows/System32/Drivers/Etc открыть на редактирование файл hosts.conf и добавить строку.
127.0.0.1 sitename
1.1.5.5 Установка сайта
Скопировать сайт в директорию хранения и обработки веб-сервером
“C:/site/sitename”.
Создать базу данных mysql с названием “kgksite”. Указать полны йдоступ с локлаьного компьютера пользователю kgkadminsite с паролем kgkpasswordadmin. (При желании можно настроить в каталоге..сайтaplicationconfig).
Загрузить дампы базы данных в базу “ kgksite ”.
Клиентская сторона:
Клиентом может являться любой ПК с любой сетевой ОС имеющий браузеры Google Chrome 12, Firefox Mozilla 10, Safari 5.1, Opera 11 и выше. Поскольку некоторые функции такие как CSS 3, HTML 5, PHP 5 не полностью поддерживаются более старыми версиями браузеров, и могут некорректно отображаться.
Набрать в поисковой строке сетевой адрес компьютера сервера.
Минимальные технические требования к ЭВМ, необходимой для нормального функционирования программного обеспечения:
1) Процессор Pentium III
2) Частота 600 Mhz
3) Оперативная память 128Mb
4) Видеокарта 64Мb
5) Клавиатура и мышь
6) Интернет связь (64 KbiteSec)
Рекомендуемые технические требования:
1) Процессор Pentium IV
2) Частота 1000 Mhz
3) Оперативная память 256Mb
4) Видеокарта 128Мb
5) Клавиатура и мышь
6) Интернет связь (512 KbiteSec)
1.1.6 Требования к информационной и программной совместимости
Программа должна работать автономно под управлением веб-серверных программ совместимых с ОС Windows 2000/XP/Vista/Seven,Unix согласно требованиям пункта 1.1.5.
1.1.7 Требования к программной документации
Основными документами, регламентирующими разработку будущих программ, должны быть документы Единой Системы Программной Документации (ЕСПД): руководство системного программиста, руководство оператору, описание программы.
1.1.8 Стадии и этапы разработки
Стадии и этапы разработки велись в соответствии с установленными сроки выполнения работы (Таблица 1).
Таблица 1. Стадии и этапы разработки
Этап |
Наименование работ |
Чем заканчивается работа |
Срок исполнения, начало окончание |
|
1 |
Анализ задания на технологической практике и подготовка раздела «Введение» |
Написание раздела «Введение» |
14.04.12 15.04.12 |
|
2 |
Подготовка раздела «Техническое задание» |
Написание раздела «Техническое задание» |
15.04.12 18.04.12 |
|
3 |
Подготовка раздела «Постановка задачи» |
Написание раздела «Постановка задачи» |
21.04.12 22.04.09 |
|
4 |
Разработка функциональной схемы модуля |
Наличие функциональной схемы модуля |
22.04.12 24.04.12 |
|
5 |
Разработка программы |
Разработка программы |
24.04.12 26.05.12 |
|
6 |
Тестирование программы |
Готовая рабочая программа |
26.05.12 28.05.12 |
|
7 |
Подготовка разделов «Заключение» и «Список литературы» |
Наличие готовых разделов |
02.06.12 06.06.12 |
|
8 |
Разработка презентационного материала |
Презентационный материал, выполненный в виде слайдов |
09.06.12 11.06.12 |
1.1.9 Порядок контроля приемки
После передачи Исполнителем программы Заказчику, последний имеет право тестировать программу в течение 7 дней. После тестирования Заказчик должен принять работу по данному этапу или в письменном виде изложить причину отказа от принятия. В случае обоснованного отказа Исполнитель обязуется доработать программу.
1.2 Обзор существующих решений
Тема «Программный комплекс управления сайтом с использованием “Kohana Framework”» была выбрана в соответствии потребностями ООО «Городское информационные сети» для разработки программы и написания дипломного проекта. Было просмотрено большое количество сайтов и программ, посвященных соответствующей тематике, и сделаны выводы, что ни один из существующих программных продуктов полностью не удовлетворяет моим требованиям к функциональным характеристикам.
Вследствие этого было решено разработать свой собственный программный продукт, который в дальнейшем может использоваться на коммерческих предприятиях как базовый шаблон программного комплекса управления сайтом.
1.3 Выбор языка программирования
Для разработки программного продукта на тему дипломного проекта мною была выбрана такая среда программирования, как PHPDesigner 8, которая является универсальным средством для создания веб-продуктов, сайтов и поддерживает подсветку большинства используемого синтаксиса в современных языках программирования, таких как PHP, Javascript, CSS, HTML, XML, SQL, Python, Perl, C# и другие. Основной язык, используемый в данном проекте PHP.
Он представляет собой интерпретатор, обладающий интуитивной и понятной средой визуального программирования, так же обладает большим наборов компонентов, предоставляет возможность создания приятного и в то же время многофункционального интерфейса, дает большие возможности для разработки Web-сервисов и работы с базами данных различных платформ, в частности с MySQL. Это лишь некоторые основные возможности PHPDesigner 8, которые повлияли на мой выбор.
На данном этапе разработки дипломного проекта были выполнены следующие задачи, а именно: была произведена конкретизация поставленной задачи, определены требования к функциональным характеристикам, требования к надежности, к составу и параметрам технических средств, к информационной и программной совместимости, проведен обзор существующих решений, а также условия эксплуатации, и обоснован выбор языка программирования.
Глава 2. Основная часть
2.1 Описание программы
2.1.1 Общие сведения
Наименование: «Программный комплекс управления сайтом с использованием “Kohana Framework”».
Данный “движок” предназначен для удобного просмотра материалов сайта, создания приоритетов доступа к материалам, надежного хранения информации, презентабельного представления опубликованных статей и анонсов предприятия.
Начальная стадия разработки интерфейса происходила совместно с разработкой сайта и написанием алгоритма, интерфейс показан на рисунке 1.
Рисунок 1. Интерфейс главной страницы
1. Голова (шапка) сайта, приветствующая часть с модулем управления.
1.а. Основное меню сайта, переключение материалов и управление действиями.
2. Текущий контент (тело) сайта, тематический материал.
3. Нижняя часть (ноги) сайта, авторские данные.
2.1.2 Функциональное назначение
Программа предназначена для удобного отображения материалов предприятия и извещения пользователей о анонсах данного предприятия.
Программный комплекс управления сайтом отображает древовидную структуру статей, в которой отображаются сведения о выбранной категории и/или их материалы.
2.1.3 Описание логической структуры
В состав данной программы входят следующие модули:
1. Главный модуль (Controller One);
1) Модули: Admin, RegisterLogin, 404Error, Materials(NSTree, CKEditor, HTMLPuriFier, ORM, EMail);
2) Сортировка записей в БД;
3) Добавление и редактирование контента;
2.1.4 Программное обеспечение, рекомендуемое для функционирования программы
Рекомендуемое клиентское программное обеспечение для наиболее корректного отображения: ОС Windows Seven, браузер Google Chrome 12.
Рекомендуемое серверное программное обеспечение для наиболее корректной работы программы: ОС Windows Seven, Apache version 2.2.17 with OpenSSL, PHP VC6 version ThreadSafe 5.3.5, MySQL Community Server version 5.5.x
Включенные модули работы short_tags и mod_ rewrite.
2.2 Руководство системного программиста
2.2.1 Общие сведения о программе
Данная программа предназначена для просмотра и редактирования информации о предприятии, а также для контроля доступа пользователей к материалам.
Программное обеспечение:
ОС MS Windows XP/Vista,/Seven/Unix;
Apache version 2.2.17 with OpenSSL;
PHP VC6 version ThreadSafe 5.3.5;
MySQL Community Server version 5.5.x;
Браузер Google Chrome 12.x
Процессор: не ниже Pentium166.
Базовый язык программирования: PHP.
2.2.2 Используемые программные средства
Программные средства:
OC - Windows 7
Apache 2.2.17 with Open SSL
PHP VC6 Version Thread Safe 5.3.5
MySQL 5.5.x
Среда разработки - PHPDesigner 8
Браузер - Google Chrome 12.x
Управление БД - Navicat 10 Premium
Дизайн - Adobe Photoshop 12.x CS5
Фреймворк - Kohana Framework 3.2.0
Структура программы:
Функциональная схема программы (Рисунок 2).
Рисунок 2. Функциональная схема программы
Структура таблиц базы данных
На рисунке 3 предоставлены диаграммы связей таблиц базы данных.
Схема не полностью отражает действительность и создана лишь графического представления работы сайта с помощью MS Access.
Рисунок 3. Схема данных
В базе данных 8 таблиц (рисунок 4, 5, 6, 7, 8, 9, 10, 11).
Рисунок 4. Таблица «regcodes»
Рисунок 5. Таблица «roles_users»
Рисунок 6. Таблица «tags_materials»
Рисунок 7. Таблица «tree»
Рисунок 8. Таблица «tags»
Рисунок 9. Таблица «roles»
Рисунок 10. Таблица «users»
Рисунок 11. Таблица «materials»
Настройка программы
Подробные сведения по настройке программы для серверной и клиентской части указаны в пункте: 1.1.5 Условия эксплуатации и требования к составу и параметрам технических средств.
2.2.3 Этапы разработки программы
Файловая система Kohana Framework представляет собой иерархическую структуру каталогов. Каждый файл, подгружаемый системой с помощью функции Kohana::find_file, по очереди ищется в следующих каталогах:
1. Папка приложения (application). Сначала Kohana ищет файл в папке вашего приложения.
2. Папка каждого из модулей (modules). Затем, файл ищется в каждой папке включенного через Kohana::modules модуля (в том порядке, в котором они определены).
3. Системная папка (system). И в последнюю очередь, Kohana ищет файл в собственной системной папке.
Всегда можно расширить функционал системы дополнительным модулем, не изменяя системный каталог (что облегчает обновление версии kohana в дальнейшем) -- достаточно создать файл с таким же именем в директории выше по приоритету чтобы переопределить файл (Рисунок 12).
Рисунок 12. Схематическое представление работы “Kohana Framework”
Разработка программы «Программный комплекс управления сайтом с использованием “Kohana Framework”» начинается с внедрения собственных страниц, использующих синтаксис Kohana и PHP в директорию разработки страничек aplication (моделей и контроллеров). Kohana -> aplication/classes/-Имя контроллера-.
Создаём новый контроллер для этого откроем среду PHPDesigner 8 и выберем ('Файл' -> 'Новый' -> PHP) и добавим начальный код для работоспособности страницы (Рисунок 13). Из выше описанного следует понимать, что контроллер является главным наследуемым классом, который тоже может наследовать системные контроллеры Фреймворка с их функциями и использовать готовые модули Фреймворка.
1) На первом этапе необходимо создать дизайн в “Adobe Photoshop CS5” и разметить его при помощи CSS и HTML на страницу (Рисунки 15 и 16).
1.1) Описать разметку базового (основного), регистрационного и авторотационного, а также просмотра материалов в CSS и HTML используя созданный шаблон в “Adobe Photoshop CS5”.
2) На втором этапе необходимо наименовать контроллер и присвоить ему контроллер от которого он будет расширяться,если таковой имеется (Рисунок 13).
2.1 Указать основной файл общего вида (отображения) (Рисунок 16).
2.2 Объявить внутренние экземпляры класса (модели), если таковые требуются (Рисунок 14).
2.3 Описать тело функции (по умолчанию index) (Рисунок 13 и 14).
2.4 Добавить и описать тела дополнительных функций, если таковые требуются (Рисунок 13 и 14).
2.5 Указать файл конкретного вида (отображения) контроллера (Рисунок 17).
3) На третьем этапе необходимо совместить отображение обработанных функций в контроллерах и их внешний вид (Рисунок 18)
Результатом выше перечисленных действий становится любая созданная страница сайта на Kohana.
Рисунок 13. Пример контроллера
Рисунок 14. Пример модели
Рисунок 15. Пример базового вида в CSS
Рисунок 16. Пример базового вида HTML+PHP
Рисунок 17. Страница наследник базового вида HTML+PHP
Рисунок 18. Совмещение видового представления где, 1 - это базовый вид, использующейся в большинстве страниц; 2 - это вид текущего контроллера, добавляется в базовый вид;
2.2.4 Проверка программы
2.2.4.1 Общие сведения о тестировании
Каждому программисту известно, сколько времени и сил уходит на отладку и тестирование программ. На этот этап приходится около 50% общей стоимости разработки программного обеспечения.
Но не каждый из разработчиков программных средств может верно определить цель тестирования. Нередко можно услышать, что тестирование - это процесс выполнения программы с целью обнаружения в ней ошибок. Но эта цель недостижима: ни какое самое тщательное тестирование не дает гарантии, что программа не содержит ошибок.
У Г.Майерса другое определение: тестирование - это процесс выполнения программы с целью обнаружения в ней ошибок. Такое определение цели стимулирует поиск ошибок в программах. Отсюда также ясно, что “удачным” тестом является такой, на котором выполнение программы завершилось с ошибкой. Напротив, “неудачным” можно назвать тест, не позволивший выявить ошибку в программе
2.2.4.2 Виды тестирования
· Тестирование модуля, или автономное тестирование (module testing, unit testing) -- контроль отдельного программного модуля, обычно в изолированной среде (т. е. изолированно от всех остальных модулей).
· Тестирование сопряжении (integration testing) -- контроль сопряжений между частями системы (модулями, компонентами, подсистемами).
· Тестирование внешних функций (external function testing) -- контроль внешнего поведения системы, определенного внешними спецификациями.
· Тестирование приемлемости (acceptance testing) -- проверка соответствия программы требованиям пользователя.
· Комплексное тестирование (system testing) -- контроль и/или испытание системы по отношению к исходным целям. Комплексное тестирование является процессом контроля, если оно выполняется в моделируемой среде, и процессом испытания, если выполняется в среде реальной, жизненной.
· Тестирование настройки (installation testing) -- проверка соответствия каждого конкретного варианта установки системы с целью выявить любые ошибки, возникшие в процессе настройки системы.
2.2.4.3 Методы тестирования
1. Существует два основных вида тестирования: функциональное и структурное. При функциональном тестировании программа рассматривается как “черный ящик” (то есть ее текст не используется). Происходит проверка соответствия поведения программы ее внешней спецификации.
Поскольку исчерпывающее функциональное тестирование невозможно, речь может идти о разработки методов, позволяющих подбирать тесты не “вслепую”, а с большой вероятностью обнаружения ошибок в программе.
2. При структурном тестировании программа рассматривается как “белый ящик” (т.е. ее текст открыт для пользования). Происходит проверка логики программы. Полным тестированием в этом случае будет такое, которое приведет к перебору всех возможных путей на графе передач управления программы (ее управляющем графе). Даже для средних по сложности программ числом таких путей может достигать десятков тысяч. Если ограничиться перебором только линейных не зависимых путей, то и в этом случае исчерпывающее структурное тестирование практически невозможно, т. к. неясно, как подбирать тесты, чтобы обеспечить “покрытие” всех таких путей.
Поэтому при структурном тестировании необходимо использовать другие критерии его полноты, позволяющие достаточно просто контролировать их выполнение, но не дающие гарантии полной проверки логики программы.
3. Метод большого скачка
Вероятно, самый распространенный подход к интеграции модулей -- метод “большого скачка”. В соответствии с этим методом каждый модуль тестируется автономно. По окончании тестирования модулей они интегрируются в систему все сразу.
Метод большого скачка по сравнению с другими подходами имеет много недостатков и мало достоинств. Заглушки и драйверы необходимы для каждого модуля. Модули не интегрируются до самого последнего момента, а это означает, что в течение долгого времени серьезные ошибки в сопряжениях могут остаться необнаруженными. Метод большого скачка значительно усложняет отладку.
И все же большой скачок не всегда нежелателен. Если программа мала и хорошо спроектирована, он может оказаться приемлемым. Однако для крупных программ метод большого скачка обычно губителен.
4. Восходящее тестирование
При восходящем подходе программа собирается и тестируется снизу вверх. Только модули самого нижнего уровня (“терминальные” модули; модули, не вызывающие других модулей) тестируются изолированно, автономно. После того как тестирование этих модулей завершено, вызов их должен быть так же надежен, как вызов встроенной функции языка или оператор присваивания. Затем тестируются модули, непосредственно вызывающие уже проверенные. Эти модули более высокого уровня тестируются не автономно, а вместе с уже проверенными модулями более низкого уровня. Процесс повторяется до тех пор, пока не будет достигнута вершина. Здесь завершаются и тестирование модулей, и тестирование сопряжении программы.
При восходящем тестировании для каждого модуля необходим драйвер: нужно подавать тесты в соответствии с сопряжением тестируемого модуля. Одно из возможных решении -- написать для каждого модуля небольшую ведущую программу. Тестовые данные представляются как “встроенные” непосредственно в эту программу переменные и структуры данных, и она многократно вызывает тестируемый модуль, с каждым вызовом передавая ему новые тестовые данные.
Имеется и лучшее решение: воспользоваться программой тестирования модулей -- это инструмент тестирования, позволяющий описывать тесты на специальном языке и избавляющий от необходимости писать драйверы.
2.2.4.4 Принципы тестирования
У Майерса сформулированы также основные принципы организации тестирования:
1. Необходимой частью каждого теста должно являться описание ожидаемых результатов работы программы, чтобы можно было быстро выяснить наличие или отсутствие ошибки в ней;
2. Следует по возможности избегать тестирования программы ее автором, т.к. кроме уже указанной объективной сложности тестирования для программистов здесь присутствует и тот фактор, что обнаружение недостатков в своей деятельности противоречит человеческой психологии (однако отладка программы эффективнее всего выполняется именно автором программы);
3. По тем же соображениям организация - разработчик программного обеспечения не должна “единолично” его тестировать (должны существовать организации, специализирующиеся на тестировании программных средств);
4. Должны являться правилом доскональное изучение результатов каждого теста, чтобы не пропустить малозаметную на поверхностный взгляд ошибку в программе;
5. Необходимо тщательно подбирать тест не только для правильных (предусмотренных) входных данных, но и для неправильных (непредусмотренных);
6. При анализе результатов каждого теста необходимо проверять, не делает ли программа того, что она не должна делать;
7. Следует сохранять использованные тесты (для повышения эффективности повторного тестирования программы после ее модификации или установки у заказчика).
2.3 Руководство оператора
2.3.1 Назначение программы
Данная программа предназначена для просмотра и редактирования информации о предприятии, а также для контроля доступа пользователей к материалам.
Программа отображает дерево подразделений организации и таблицу, в которой отображаются телефонные номера, которые находятся в данном подразделении. При выборе конкретного телефонного номера на экран выводится подробная информация о нем.
2.3.2 Условия выполнения программы
Условия необходимые для выполнения программы.
Минимальные:
1) Процессор Pentium III
2) Частота 600 Mhz
3) Оперативная память 128Mb
4) Видеокарта 64Мb
5) Клавиатура и мышь
6) Интернет связь (64 KbiteSec)
2.3.3 Выполнение программы
Запуск браузера и переход на адрес сайта (Рисунок 18).
Переходим в меню “Регистрация” и заполняем поля для регистрации на сайте (Рисунок 19).
Рисунок 19. Страница регистрации на сайте
1. Все поля валидируются на наличие вредоносного кода и случайных ошибок заполнения предусмотренных классом регистрации “Reg” в контроллере “Authformer” и его дочерними функциями.
2. Генерируется динамическое изображение для исключения ботов регистрации. С функцией обновления для удобства осмотра пользователем.
3. При валидном заполнении формы данные пересылаются методом POST на обработку модели Reg и ее дочерним функциям, иначе выносится сообщение ошибки пользователю.
4. Данные временно записываются в базу данных. Пароль шифруется.
5. Пользователю высылается письмо на Email с кодом подтверждения регистрации, принимаемым по ссылку методом GET.
6. Пользователь закрепляется в базе данных и получает определенные права.
После регистрации и ее подтверждения по электронной почте, мы можем войти на сайт как пользователь используя “Авторизацию” (Рисунок 20) и получить доступ к просмотру материалов и категорий сайта.
Рисунок 20. Авторизация-1
1. Первичная авторизация (без генерирования динамического изображения защиты от повторного ввода) позволяет пользователю ввести свои данные и войти на сайт как пользователь.
2. В случае удачного входа пользователь попадает на страницу к которой возможно обращался ранее (с помощью сессий), но не смог получить доступ без авторизации. Если вход выполнен неудачен пользователь переносится на страницу Авторизации-2 с защитой от перебора пароля динамически генерируемым изображением.
3. На форме имеется ссылка на страницу регистрации
4. На форме имеется ссылка на страницу восстановление пароля;
5. Имеется кнопка скрыть
Рисунок 16. Авторизация-2
1. Вторичная авторизация срабатывает, когда пользователь вводит неправильно данные в первичной форме авторизации.
2. Динамически генерируемое изображение для защиты от переборки пароля (с функцией обновления для удобства осмотра пользователем).
3. В остальном работа аналогична первичной форме авторизации.
Рисунок 17. Восстановление пароля
1. Форма работает с использованием Ajax. При вводе E-mail'a. Мгновенная проверка существования E-mail'a в БД.
2. Пользователь получает ответ в виде зеленой галочки или же красного крестика.
3. Обработка запроса и генерирование нового пароля с отсылкой на Email пользователя
Рисунок 18. Пример категории и материалов
1. При выборе категории пользователь получает вид принадлежащих ей материалов.
Рисунок 19. Пример вида материала
1. При выборе материала в категории пользователь получает вид статьи.
Рисунок 19. Страница администрации - добавление
1. Страница с ограниченным по роли пользователя доступом (только для администраторов сайта).
2. Возможность создания категорий
3. Возможность добавление материалов в категории
4. Возможность добавление темовых тегов к материалам
5. Использование текстового модуля “Ckeditor” для улучшения визуализации текстового поля.
6. Проверка вредоносности введенных данных в поля с помощью модуля “htmlpurifier”.
Рисунок 19. Страница администрации - пользователи
1. Поиск пользователя в базе данных сайта.
2. Отображение количества зарегистрированных пользователей.
3. Отображение количества администраторов среди пользователей.
Глава 3 Экономическая часть
3.1 Расчет времени на создание программного продукта
Затраты времени на создание программного продукта дает трудоемкость.
Трудоемкость измеряет человека в часах, в днях и она является обратным показателем производительности труда т.е снижая трудоемкость по большому счету повышается производительность труда который является единственным источником роста благосостояния личности хозяйственного субъекта и в целом экономики.
Структура общего времени на создание программного продукта представлена в табл.2
Таблица 2. Общее время на создание программного продукта.
№ этапа |
Обозначение времени данного этапа |
Содержание этапа |
|
1 |
Тпо |
Подготовка описания задачи |
|
2 |
То |
Описание задачи |
|
3 |
Та |
Разработка алгоритма |
|
4 |
Тбс |
Разработка блок-схемы алгоритма |
|
5 |
Тн |
Написание программы на языке PHP |
|
6 |
Тп |
Набивка программы |
|
7 |
Тот |
Откладка и тестирование программы |
|
8 |
Тд |
Оформление документации, инструкции пользователю, пояснительной записки |
Время рассчитывается в человеко-часах, причем Тпо берется по фактически отработанному времени (исходные данные), а время остальных этапов определяется расчетом по условному числу команд Q.
Условное число команд определяется по формуле:
Q=q*c
где q - коэффициент, учитывающий условное число команд.
Выбрать значение коэффициента q можно из табл.3
Таблица 3. Коэффициент числа команд.
Тип задачи |
Пределы измерений коэффициента |
|
Задачи учета |
от 1400 до 1500 |
|
Задачи оперативного управления |
от 1500 до 1700 |
|
Задачи планирования |
от 3000 до 3500 |
|
Многовариантные задачи |
от 4500 до 5000 |
|
Комплексные задачи |
от 5000 до 5500 |
где c - коэффициент, учитывающий новизну и сложность программы.
Программные продукты по степени новизны отнесены к одной из 4-х групп:
- группа А - разработка принципиально новых задач;
- группа Б - разработка оригинальных программ;
-группа В - разработка программ с использованием типовых решений;
- группа Г - разовая типовая задача.
По степени сложности программные продукты могут быть отнесены к одной из 3-х групп:
-1- алгоритм оптимизации и моделирования систем;
-2- задачи учета, отчетности и статистики;
-3-стандартные алгоритмы.
Коэффициент С определяется из табл.4 на пересечении групп сложности новизны.
Таблица 4. Сложность программы.
Язык программирования |
Группа сложности |
Степень новизны |
||||
А |
Б |
В |
Г |
|||
Высокого уровня |
1 |
1,38 |
1,26 |
1,15 |
0,69 |
|
2 |
1,30 |
1,19 |
1,08 |
0,65 |
||
3 |
1,20 |
1,10 |
1,00 |
0,60 |
||
Низкого уровня |
1 |
1,58 |
1,45 |
1,32 |
0,79 |
|
2 |
1,49 |
1,37 |
1,24 |
0,74 |
||
3 |
1,38 |
1,26 |
1,15 |
0,69 |
||
Так как разрабатываемый программный продукт предназначен для решения задач учета, то коэффициент q, выбранный из таблицы 3 равен 1500.
Программа написана на языке высокого уровня и является разовой типовой задачей, следовательно, относится к группе «Г». По степени сложности ПП относится к группе стандартные алгоритмы (группа 3). Из таблицы 4 выбираем соответствующую позицию, равную 0,60. Далее подставляем выбранные данные в формулу:
Q=1500*0,60 =900
Определяем время, затраченное на каждый этап создания программного продукта:
1) Тпо берется по факту. Оно равно 7 (человеко/часов).
2) То определяется по формуле:
То=Q*B/(50*K)
где В - коэффициент учета изменений задачи. Он равен 1,3.
К - коэффициент, учитывающий квалификацию программиста. Выбрать значение коэффициента К можно из табл.5
Таблица 5. Коэффициент квалификации программиста
Стаж программиста |
Значение коэффициента К |
|
до 2-х лет |
0,8 |
|
от 2 до 3 лет |
1,0 |
|
от 3 до 5 лет |
1,1 - 1,2 |
|
от 5 до 10 лет |
1,2 - 1,3 |
|
свыше 10 лет |
1,3 - 1,5 |
Так как стаж программиста до 2-х лет, то подставляем в формулу коэффициент 0,8.
То=900*1,3/(50*0,8)=29,25(челчас)
3)Та рассчитываем по формуле:
Та=Q/(50*K)
Та=900/(50*0,8) =22,5(челчас)
4)Тбс определяется аналогично Та
Тбс= Та = Q/(50*K)
Тбс= Та = 900/(50*0,8) =22,5(челчас)
5)Тн определяется по формуле:
Тн=Q*1,5/(50*K)
Тн=900*1,5/(50*0,8)=33,75 (челчас)
6)Тп определяется по формуле:
Тп=Q/50
Тп=900/50=18(челчас)
7)Тот определяется по формуле:
Тот=Q*4,2/50*K
Тот=900*4,2/50*0,8=94,5(челчас)
8) Тд определяется аналогично Тпо
Тд=Тпо=7 (чел/час)
Теперь зная время, затраченное на каждом этапе, можно подсчитать общее время на создание программного продукта:
Т=Тпо+То+Та+Тбс+Тн+Тп+Тот+Тд
Т=7+29,25+22,5+22,5+33,75+18+94,5+7=234,5 (челчас)
3.2 Расчет годового фонда заработной платы исполнителя по созданию программного продукта
Фонд заработной платы состоит из основной и дополнительной зарплаты.
Основная заработная плата включает оплату по отдельным расценкам, тарифным ставкам, должностному окладу, премии (40%).
Дополнительна заработная плата - это оплата отпусков (11,4%) доплата по территориальному коэффициенту (15%).
Основная ЗП определяется по формуле:
ЗПосн=Х*Кт*Т/Чр*tp.д*(1+П/100)
Где Х- среднемесячная ЗП программиста (руб)- определяется самостоятельно по рыночной ситуации;
Кт- тарифный коэффициент, соответствующий разряду тарифной сетки по которому работает исполнитель (1,3);
Т-общее время на создание программного продукта (чел/час);
Чр- число рабочих дней в месяце (30 дней);
tp.д - продолжительность рабочего дня в часах (8 часов);
П - процент премии.
Рассчитываем зарплаты разработчику:
ЗПосн=23000*1,3*234,5/30*8*(1+40/100)=20867,70 (рублей)
Дополнительная ЗП берется в размере 11,4% от основной.
ЗПд= 39706,10*11,4%=2378,91 (рублей)
Общая ЗП будет равна сумме основной и дополнительной:
ЗПобщая=ЗПосн+ЗПдоп
ЗПобщая=20867,70 +2378,91 =23246,61 (рублей)
3.3 Расчет начислений на заработную плату
Социальное страхование в РФ является обязательным каждый хозяйствующий субъект, любой организационно правовой формы собственности отчисляет денежные средства в фонд ЗП во внебюджетные фонды отчисляют на:
1.Фонд социального страхования (ФСС) - 2,9 %
2. Пенсионный фонд России (ПФР) - 22 %
3.Федеральный фонд обеспечения медицинского страхования (ФФОДС) - 5,1 %
Отчисления на социальное страхование, начисляется с заработной платы и включаются в себестоимость программного продукта.
ФСС = ЗП общая * 2,9%
ПФР = ЗП общая * 22%
ФФОДС = ЗП общая * 5,1%
ФСС = 23246,61 * 2,9%=674,15 (рублей)
ПФР = 23246,61 * 22%=5114,25 (рублей)
ФФОДС = 23246,61 * 5,1%=1185,57 (рублей)
Общая сумма отчислений на социальное страхование:
674,15 + 5114,25 + 1185,57 = 6973,97 (рублей)
3.4 Расчет расходов на содержание и эксплуатацию ПЭВМ
Расходы на содержание и эксплуатацию ПЭВМ рассчитываются по следующим статьям:
1)Основная ЗП работников, обеспечивающих функционирование ПВЭМ.
Для системных программистов: Нобсл=25, Кт=2,02
ЗПосн.год.=(Х*Кт/Нобсл.)*((1+П/100)*12)
Средняя заработная плата системного программиста составляет 10000 рублей. Подставляем данные в формулу:
ЗПосн.год.=(10000*2,02/25.)*((1+40/100)*12)=3975,36 (рублей)
2)Дополнительная ЗП обслуживающего персонала - 11,3% от основной заработной платы
ЗПд=3975,36 *11,3=449,21 (рублей)
Общая ЗП будет равна сумме основной и дополнительной:
ЗПобщая=ЗПосн+ЗПдоп
ЗПобщая=3975,36 +449,21 =4424,57 (рублей)
3)Начисления на ЗП обслуживающего персонала (30%):
Нзп=ЗПгод.о.п*30%
Нзп=4424,57 *30%=1327,37 (рублей)
4) Социальные отчисление с заработной платы вспомогательного персонала - СОвп (30% от общей заработной платы)
СОвп=4424,57 *30%=1327,37 (рублей)
5)Амортизационные отчисления определяются в размере 25% от балансовой стоимости ЭВМ (Кб)(исходные данные).
А=Кб*25 %
А=25000*25 %=6250 (рублей)
6)Затраты на электроэнергию:
Зс.эн(осв)=Фэф * Цэ * P
Фэф - эффективный годовой фонд работы ПЭВМ в часах (2016 часов)
Цэ - стоимость 1кВт/ч.
P - мощность ПЭВМ с периферией в кВт/ч.
P= 0,7-1,2- в зависимости от периферии (определяется самостоятельно)
Так как ПП разрабатывался в Москве, то стоимость 1кВт/ч составляет 2,66 рубля, а коэффициент периферии Р равен 1,2. ПП разрабатывается 234,5 часов, поэтому Фэф=234,5.
Зс.эн(осв)= 234,5* 2,66 * 1,2=748,52 (рублей)
7) Расходы на профилактику составляют 2% от балансовой стоимости ПВЭМ с периферией.
Зпроф = Кб * 2%, где Кб - стоимость ПЭВМ
При разработке данного ПП использовался ноутбук марки HP модели, рыночная стоимость которого составляет 25000 рублей. Следовательно, Кб=25000. А затраты на профилактику:
Зпроф = 25000 * 2%=500 (рублей)
8) Прочие производственные расходы (Ппр) берутся в размере 30% от основной ЗП работников, обеспечивающих функционирование ЭВМ.
Ппр=ЗПобсл*30%=4424,57 *30%=1327,37 (рублей)
9) Определяем годовые расходы на содержание и эксплуатацию 1-ой ЭВМ, для этого складываем все компоненты:
З общие = ЗП общая + Нзп + СОвп + А + Зс.эн(осв) + Зпроф + Ппр
З общие = 4424,57 + 1327,37 + 1327,37 + 6250+ 748,52 + 500 + 1327,37 =15905,2 (рублей)
Далее определяем себестоимость 1-го машино-часа работы ПВЭМ, которая определяется по формуле:
Смч=Зобщ/12/30/8*Т
Смч=15905,2/30/12/8*234,5=1295,05 (рублей)
3.5 Расчет себестоимости программного продукта
Себестоимость продукции представляет собой стоимостную оценку используемых в процессе производства продукции природных ресурсов, сырья, материалов, топлива, энергии, основных фондов, трудовых ресурсов, а также затрат связанных с реализацией.
В себестоимость программного продукта входят следующие элементы:
1)Основная ЗП исполнителя работ по созданию программного продукта;
2)Дополнительная ЗП исполнителя работ по созданию программного продукта;
3)Начисления на ЗП:
4)Расходы на содержание и эксплуатацию ПВЭМ, относящихся к данному программному продукту;
5)Прочие расходы.
Первые 4 элемента уже известны, а прочие расходы составляют 10% от суммы первых 4-х элементов.
Структуру себестоимости программного продукта опишите в таблице 6.
Таблица 6. Расчет себестоимости.
№ |
Элементы себестоимости |
Сумма (руб) |
% в общей сумме себестоимости |
|
1 |
Основная ЗП исполнителя |
20867,70 |
41,13 |
|
2 |
Доп. ЗП исполнителя |
2378,91 |
4,69 |
|
3 |
Начисления на ЗП |
6973,97 |
13,74 |
|
4 |
РС и ПЭВМ |
15905,2 |
31,35 |
|
5 |
Прочие расходы |
4612,57 |
9,09 |
|
Итого: |
50738,35 |
100 |
3.6 Расчет цены программного продукта
Цена - это денежное выражение стоимости продукции.
Цена складывается из нескольких компонентов:
Ц=С+П+НДС
Где С - себестоимость программного продукта
П - прибыль, которую берем в размере 40% от себестоимости
НДС- налог на добавленную стоимость, который берется в размере 18% от суммы себестоимости и прибыли.
Ц=50738,35+(50738,35*40%)+((50738,35+(50738,35*40%))*18%)
=83819,75 (рублей)
3.7 Расчет экономической эффективности
Эффективность это результативность т.е. получение результата с учетом затрат - более того с минимальными затратами трудовых, материальных, финансовых средств труда.
(проект считается эффективным, если показатель составляет более 15%)
? Пр = приблизительный рост прибыли за два года
КВ - капитальные вложения = себестоимость программного продукта
? Пр=Пр2года-Пр1года
Пр2года берется в размере 65% от себестоимости.
? Пр=(50738,35*65%)-20295.34=12684,58(рублей)
Находим Эа:
Эа=12684,58/50738,35=0,24=24%
3.8 Вывод
В экономической части ДП произведен расчет себестоимости и цены программного продукта «Разработка: Программный комплекс управления сайтом с использованием “Kohana Framework”»,которая показала эффективность создания данного программного продукта, т.к. экономическая эффективность составляет 24 %.
Расчеты отвечают современным требованиям ведения бухгалтерского учета и плановой политики предприятий.
Программа полностью соответствует современным требованиям и стандартам.
программный управление сайт оператор
Глава 4 Техника безопасности при работе по эксплуатации (ПК)
4.1 Общие положения
Работа на компьютере связана со значительной концентрацией внимания, зрительным напряжением и эмоциональной нагрузкой. Во время работы компьютера создаются специфические условия микроклимата: повышается температура воздуха, понижается влажность, изменяется ионный состав воздуха. Наблюдается также повышенный уровень электромагнитных излучений, статическое электричество.
Эти явления могут вызвать отклонения в состоянии здоровья, которые проявляются в первую очередь в том, что у человека снижается работоспособность, быстро наступает зрительное утомление, затем появляются признаки ухудшения зрения, нарушения функционального состояния центральной нервной системы. Пока последствия работы с компьютером не изучены до конца. Однако выяснено, что наибольшую опасность представляет электромагнитное излучение. Его уровень превышает допустимые нормативы в 2-5 раз, в то время как уровни ультрафиолетового и инфракрасного излучения значительно ниже принятых гигиенических нормативов, а рентгеновское излучение практически отсутствует.
В последние годы появляются сообщения о возможности индукции электромагнитными излучениями злокачественных заболеваний. Немногочисленные данные говорят о том, что наибольшее число случаев приходится на опухоли кроветворных органов и на лейкоз в частности.
Статистика дает такую информацию об основных заболеваниях при работе с компьютером:
* Заболевания органов зрения - 60% пользователей
* Сердечно-сосудистая система-60%
* Желудочно-кишечный тракт -40%
* Кожные заболевания -10%
Для снижения вредного воздействия компьютера на человека необходимо соблюдать определенные требования к условиям работы, к рабочему месту; компьютер должен соответствовать гигиеническим требованиям. Кроме того, необходимо строго соблюдать режим работы на компьютере.
4.2 Эксплуатация ЭВМ (ПК)
На основе сказанного можно сформулировать определенные рекомендации для пользователей персональных компьютеров с точки зрения охраны их труда. Основной подход к решению проблем такого рода сводится к установлению строгого контроля за соответствием аппаратных и программных средств, а так же условий их эксплуатации в соответствии с эргономическими требованиями. Это служит основой для выработки следующих общих рекомендаций: - соблюдение ограничений по медицинским показаниям;
- внимательное отношение к характеристикам дисплеев;
- правильная организация рабочих мест операторов;
- правильная организация работы с ПК;
- соблюдение мер защиты от поражения электрическим током. Раскрывая их, можно сформулировать рекомендации следующего характера:
- необходимо соблюдать ограничение на работу с ПК, для служащих, страдающих заболеваниями опорно-двигательного аппарата, глаз (или нарушениями зрения.), кожи, а также для беременных женщин (во всех случаях лучше получить консультацию у врача);
предпочтительнее использовать дисплеи с достаточно высокой разрешающей способностью;
- лучше выбирать видеоадаптеры с достаточно высоким разрешением и по возможности (если есть на рынке и цена приемлемая) с частотой обновления экранного изображения не менее 70 - 72 Гц;
-обязательно ставить на дисплеи экраны, в частности поляризационные, фильтры, в несколько раз снижающие утомляемость глаз;
- если позволяют условия, то рекомендуется сидеть не ближе 70 см (примерно на расстоянии вытянутой руки) от дисплея;
- экран дисплея не должен быть ориентирован в сторону источников света (окон, настольных ламп и т.п.);
- при размещении рабочего места рядом с окном угол между экраном дисплея и плоскостью окна должен составлять не менее 90 градусов (для исключения бликов), прилегающую часть окна желательно зашторить;
- не следует располагать дисплей непосредственно под источником освещения или вплотную с ним;
- желательно, чтобы освещенность на рабочем месте оператора ПК не превышала 2/3 нормальной освещенности помещения;
- общее время работы с дисплеем не должно превышать 50% от полного рабочего времени оператора;
- не следует превышать темп работы порядка 10000 нажатий клавиш в час;
- при обычной работе с компьютером необходимо делать 15 -минутные перерывы через каждые два часа, а при интенсивной работе - через каждый час.
Заключение
Тема дипломного проекта была выбрана в соответствии с заданием, выданном руководителем преддипломной практики.
В первой главе выполнены следующие задачи, а именно: конкретизирована постановка задачи, проведён обзор существующих решений и обоснован выбор языка программирования.
Во второй главе выполнены следующие задачи, а именно: разработана структурная схема, разработан интерфейс программного продукта, определены технические требования к оборудованию, на котором будет выполняться разработанная программа, проведён тест программного продукта, разработано руководство оператора и системного программиста.
В третьей главе выполнена задача по составлению сметы затрат на программный продукт.
Подводя итоги выполненного задания, следует отметить, что в нём были достигнуты поставленная цель и задачи.
Список литературы
1. ГОСТ 19.402 - 78. Описание программы.
2. ГОСТ 19.503 - 79. Руководство системного программиста. Требования к содержанию и оформлению.
3. ГОСТ 19.505 - 79. Руководство оператора. Требования к содержанию и оформлению.
4. ГОСТ 24.207 - 80. Требования к содержанию документов по программному обеспечению.
5. Колисниченко Д.Н. Самоучитель PHP5: в теории и на практике - 2007г.
6. Jason D. Straughan. Kohana 3.0. Beginner's Guide - 2011г.
7. http://kohanaframework.org/
8. http://ru.wikipedia.org/wiki/Kohana
9. http://www.sdelaysite.com/php/php-1
10. http://kohana3.ru/
11. http://www.webcorp.ru/page/cmsabout.html
12. http://habrahabr.ru/hub/kohanaphp/
13. http://blogocms.ru/category/tryuki-vebmastera/kohana/
14. http://forum.php.su/
15. http://vremenno.net/html-css/css3-review/
16. http://1popov.ru/bonuscourse/cssform/
17. http://ckeditor.com/
18. http://htmlpurifier.org/
19. http://github.com
20. http://www.apache.org/
21. http://www.php.net/
22. http://www.mysql.com/
23. http://validator.w3.org/
Приложение. Код программы
..cssauth.css
@charset 'UTF-8';
#close-button{
position: absolute;
z-index:30;
bottom: 4px;
right: 2px;}
#ptext{
margin: 5px 0 0 0;}
#slider p a,#close-button{
color: #000;}
.btmimg:hover{
background-image: url(/img/buttonover.png);
background-repeat: no-repeat;
width: 110px;
height: 45px;
margin: 0 auto;
padding-top: 2px;
border: none;}
.btmimg{
background-image: url(/img/buttonout.png);
background-repeat: no-repeat;
width: 110px;
height: 45px;
margin: 0 auto;
border: none;}
#slider{
font-size: 12px;
font-family: verdana, sans-serif;
color: #333;
position:absolute;
top:-56px;
right:-80px;
z-index:2;
width:200px;
text-align: center;
padding-bottom: 2px;}
#slider-in{
position:relative;
z-index:3;
height:0;
overflow:hidden;
background: rgb(245,246,246); /* Old browsers */
/* IE9 SVG, needs conditional override of 'filter' to 'none' градиент-диагональный */
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+CiAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZjVmNmY2IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMjElIiBzdG9wLWNvbG9yPSIjZGJkY2UyIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDklIiBzdG9wLWNvbG9yPSIjYjhiYWM2IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iODAlIiBzdG9wLWNvbG9yPSIjZGRkZmUzIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2Y1ZjZmNiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
background: -moz-linear-gradient(-45deg, rgba(245,246,246,1) 0%, rgba(219,220,226,1) 21%, rgba(184,186,198,1) 49%, rgba(221,223,227,1) 80%, rgba(245,246,246,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,rgba(245,246,246,1)), color-stop(21%,rgba(219,220,226,1)), color-stop(49%,rgba(184,186,198,1)), color-stop(80%,rgba(221,223,227,1)), color-stop(100%,rgba(245,246,246,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(-45deg, rgba(245,246,246,1) 0%,rgba(219,220,226,1) 21%,rgba(184,186,198,1) 49%,rgba(221,223,227,1) 80%,rgba(245,246,246,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(-45deg, rgba(245,246,246,1) 0%,rgba(219,220,226,1) 21%,rgba(184,186,198,1) 49%,rgba(221,223,227,1) 80%,rgba(245,246,246,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(-45deg, rgba(245,246,246,1) 0%,rgba(219,220,226,1) 21%,rgba(184,186,198,1) 49%,rgba(221,223,227,1) 80%,rgba(245,246,246,1) 100%); /* IE10+ */
background: linear-gradient(-45deg, rgba(245,246,246,1) 0%,rgba(219,220,226,1) 21%,rgba(184,186,198,1) 49%,rgba(221,223,227,1) 80%,rgba(245,246,246,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f6f6', endColorstr='#f5f6f6',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */
box-shadow: 0 0 50px #40310a; /* тень - размытая */}
..cssstylesheet.css
@charset 'UTF-8';
@import url(auth.css);
body {
margin:0px;
padding:0px;
min-height: 800px;
min-width: 1024px;
background-attachment: scroll;
background-image: url(../img/background.jpg);
background-repeat: repeat-x;
background-position: left top;}
#content_container {
position: relative;
margin: 0 auto;
width:900px;
min-height: 550px;
background-attachment: scroll;
background-image: url(../img/Untitled-4.png);
background-repeat: no-repeat;
background-position: right center;}
#logo_container {
height:90px;
width:900px;
margin: 0 auto;
min-width: 900px;}
#main_container {
height:70px;
width:900px;
margin: 0 auto;}
#logo_image {
width:255px;
height:75px;
margin-left:10px;
margin-top:15px;
float:left;
background-image: url(../img/logo.png);}
#top_bar_black {
width:100%;
height:90px;
background-color:#000000;}
#bottom_bar_black {
width:100%;
height:80px;
background-color:#000000;}
#nav_block {
width: 500px;
height:90px;
float:right;}
.nav_button {
width: 70px; /*This number you can edit when you need to add more with to fit your text inside the button */
color:#FFFFFF;
font-family:Verdana, Arial, Helvetica, sans-serif;
font-style: italic;
font-size:12px;
margin-left:10px;
margin-top:35px;
text-align:center;
float:left;}
a:hover{
font-style: normal;
font-weight: bold;
color: #fff; }
a {
text-decoration: none;
font-style: italic;
font-weight: normal;
color: #fff;
font-family:Verdana, Arial, Helvetica, sans-serif;
font-style: italic;
font-size:12px; }
#header {
width:500px;
margin-top:50px;
margin-bottom:250px;
float: left;}
.header_content_mainline {
font-size:35px;
color:#000000;
width:500px;
font-style: italic;}
#header_content_boxline {
font-size:35px;
color:#000000;
width:400px;
font-style: italic;}
#header_content_lowerline {
font-size:35px;
color:#FFFFFF;
width:400px;
font-style: italic;}
#header_content_boxcontent {
font-size:12px;
color:#333333;
width:400px;
font-style: italic;}
#header_content_lowerboxcontent {
font-size:12px;
color:#CCCCCC;
width:400px;}
#header_content_tagline {
font-size:12px;
color:#333333;
width:500px;}
#header_lower {
width:400px;
float:left;
margin-right:40px;
margin-bottom:50px;}
#copywriteblock {
margin: 10px auto;
width: 900px;
color:#333333;
font-size:10px;
font-family: verdana;
text-align:right;
text-decoration:none;}
#copywriteblock a{
color: #222;}
#copywriteblock a:hover{
color: #555;}
#clear{clear: both;}
..cssstylesheetadmin.css
@charset 'UTF-8';
body {
margin:0px;
padding:0px;
min-height: 800px;
min-width: 1024px;
background-attachment: scroll;
background-image: url(../img/background.jpg);
background-repeat: repeat-x;
background-position: left top;}
#content_container {
position: relative;
margin: 0 auto;
width:900px;
min-height: 550px;
background-attachment: scroll;
background-image: none;
background-repeat: no-repeat;
background-position: right center;}
#logo_container {
height:90px;
width:900px;
margin: 0 auto;
min-width: 900px;}
#main_container {
height:70px;
width:900px;
margin: 0 auto;}
#logo_image {
width:255px;
height:75px;
margin-left:10px;
margin-top:15px;
float:left;
background-image: url(../img/logo.png);}
#top_bar_black {
width:100%;
height:90px;
background-color:#000000;}
#bottom_bar_black {
width:100%;
height:80px;
background-color:#000000;}
#nav_block {
width: 500px;
height:90px;
float:right;}
.nav_button {
color:#FFFFFF;
font-family:Verdana, Arial, Helvetica, sans-serif;
font-style: italic;
font-size:12px;
margin-left:15px;
margin-top:35px;
text-align:center;
float:left;}
a:hover{
font-style: normal;
font-weight: bold;
color: #fff; }
a {
text-decoration: none;
font-style: italic;
font-weight: normal;
color: #fff;
font-family:Verdana, Arial, Helvetica, sans-serif;
font-style: italic;
font-size:12px; }
#header {
width:500px;
margin-top:50px;
margin-bottom:250px;
float: left;}
.header_content_mainline {
font-size:35px;
color:#000000;
width:500px;
font-style: italic;}
#header_content_boxline {
font-size:35px;
color:#000000;
width:400px;
font-style: italic;}
#header_content_lowerline {
font-size:35px;
color:#FFFFFF;
width:400px;
font-style: italic;}
#header_content_boxcontent {
font-size:12px;
color:#333333;
width:400px;
font-style: italic;}
#header_content_lowerboxcontent {
font-size:12px;
color:#CCCCCC;
width:400px;}
#header_content_tagline {
font-size:12px;
color:#333333;
width:500px;}
#header_lower {
width:400px;
float:left;
margin-right:40px;
margin-bottom:50px;}
#copywriteblock {
margin: 10px auto;
width: 900px;
color:#333333;
font-size:10px;
font-family: verdana;
text-align:right;
text-decoration:none;}
#copywriteblock a{
color: #222;}
#copywriteblock a:hover{
color: #555;}
#clear{clear: both;}
input{
padding: 0 10px;
margin: 5px;}
..aplicationclassesadminverification.php
<?php defined('SYSPATH') or die('No direct script access.');
class Adminverification extends Controller_Template
{
public function before()
{
$session = Session::instance();
$session->set('auth_redirect', $_SERVER['REQUEST_URI']);
$auth=Auth::instance();
if($auth->logged_in() == 0 ) Request::initial()->redirect('authformer');
if($auth->logged_in('admin') == 0 ) Request::initial()->redirect('netprav');
return parent::before();
}
}
..aplicationclasseschildrenbefore.php
<?php defined('SYSPATH') or die('No direct script access.');
class Childrenbefore extends Controller_Template
{
public function before()
{
$session = Session::instance(); // Создание эземпляра класса Session на основе метода Instance
$session->set('auth_redirect', $_SERVER['REQUEST_URI']); // запись в переменную session методом set страницы которую хотел посетить пользователь
$auth=Auth::instance(); // объявление экземпляра класса авторизации
if($auth->logged_in() == 0) Request::initial()->redirect('authformer'); // если пользователь не авторизован переадресовать его на страницу авторизации
return parent::before();
}
}
..aplicationclassesexception404.php
<?php defined('SYSPATH') or die('No direct script access.');
class Exception404
{
public static function handle(Exception $e) // На вход приходит ошибка
{
switch (get_class($e))
{
case 'HTTP_Exception_404':// сравнивается с 404
$response = new Response;
$response->status(404);// в статус сервера 404
$view = new View('404view'); // использовать вид view404
$view->message = $e->getMessage(); // записать в переменную $message сообщение из контроллера materials -- throw new HTTP_Exception_404('Страница не найдена!');
echo $response->body($view)->send_headers()->body();// генерация отображения
return TRUE;
break;
default:// если не 404 обрабатывать стандартными методами Kohana
return Kohana_Exception::handler($e);
break;
}
}
}
..aplicationclassesloginverification.php
<?php defined('SYSPATH') or die('No direct script access.');
class Loginverification extends Controller_Template
{
public function before()
{
$session = Session::instance();
$session->set('auth_redirect', $_SERVER['REQUEST_URI']);
$auth=Auth::instance();
if($auth->logged_in() == 0 ) Request::initial()->redirect('authformer');
return parent::before();
}
}
..aplicationclassesnstree.php (готовый модуль для работы категорий)
<?php defined('SYSPATH') or die('No direct script access.');
/*
CREATE TABLE `tree` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`left_key` INT(10) NOT NULL,
`right_key` INT(10) NOT NULL,
`level` INT(10) NOT NULL,
PRIMARY KEY (`id`),
INDEX `key` (`left_key`, `right_key`, `level`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
*/
class NSTree
{
protected $table = NULL;
public function __construct($tablename)
{
$this->table = $tablename;
}
// Модифицирует ключи
protected function modifyNodes($key, $delta)
{
$query =
'UPDATE '.Database::instance()->quote_table($this->table).'
SET right_key = right_key + '.(int)$delta.'
WHERE right_key >= '.(int)$key;
DB::query(Database::UPDATE, $query)->execute();
$query =
'UPDATE '.Database::instance()->quote_table($this->table).'
SET left_key = left_key + '.(int)$delta.'
WHERE left_key >= '.(int)$key;
DB::query(Database::UPDATE, $query)->execute();
}
public function getNode($id)
{
$result = DB::select()
->from($this->table)
->where('id', '=', $id)
->execute();
if (count($result) == 0)
throw new Exception('Node id='.$id.' does not exist.');
return $result->current();
}
public function clear($extrafields=array())
{
if (!is_array($extrafields))
throw new Exception('$extrafields must be array.');
DB::query(NULL, 'TRUNCATE '.Database::instance()->quote_table($this->table))->execute();
DB::delete($this->table)->execute();
$data = array(
'id' => 1,
'name' => '<root>',
'left_key' => 1,
'right_key' => 2,
'level' => 0
);
$data = $data + $extrafields;
list($insert_id, $tmp) = DB::insert($this->table, array_keys($data))->values(array_values($data))->execute();
return $insert_id;
}
public function getTree($id=NULL)
{
$id = (int) $id;
$QTblName = Database::instance()->quote_table($this->table);
if ($id != 0)
{
$node = $this->getNode($id);
$query =
'SELECT *
FROM '.$QTblName.'
WHERE left_key >= '.(int)$node['left_key'].' AND right_key <= '.(int)$node['right_key'].'
ORDER BY left_key';
}
else
{
$query =
'SELECT *
FROM '.$QTblName.'
ORDER BY left_key';
}
$result = DB::query(Database::SELECT, $query)->execute();
return $result;
}
public function getPath($id)
{
$node = $this->getNode($id);
$query =
'SELECT *
FROM '.Database::instance()->quote_table($this->table).'
WHERE right_key > '.(int)$node['left_key'].' AND left_key < '.(int)$node['right_key'].'
ORDER BY left_key';
$result = DB::query(Database::SELECT, $query)->execute();
return $result;
}
public function insert($id, $extrafields=array())
{
if (!is_array($extrafields))
throw new Exception('$extrafields must be array.');
// Находим родителя
$parent = $this->getNode($id);
DB::query(NULL, 'START TRANSACTION')->execute();
// Обновляем ключи существующего дерева, узлы стоящие за родительским узлом
$this->modifyNodes((int)$parent['right_key'], 2);
// Добавляем новый узел
$node = array(
'id' => NULL,
'left_key' => $parent['right_key'],
'right_key' => $parent['right_key'] + 1,
'level' => $parent['level'] + 1
);
$node = $node + $extrafields;
list($insert_id, $tmp) = DB::insert($this->table, array_keys($node))->values(array_values($node))->execute();
DB::query(NULL, 'COMMIT')->execute();
return $insert_id;
}
public function delete($id)
{
$node = $this->getNode($id);
DB::query(NULL, 'START TRANSACTION')->execute();
// Удаляем узел (вместе с веткой)
$query =
'DELETE FROM '.Database::instance()->quote_table($this->table).'
WHERE left_key >= '.(int)$node['left_key'].' AND right_key <= '.(int)$node['right_key'];
DB::query(Database::DELETE, $query)->execute();
$width = $node['right_key'] - $node['left_key'] + 1;
// Обновление последующих узлов
$this->modifyNodes((int)$node['right_key'], -$width);
DB::query(NULL, 'COMMIT')->execute();
}
// Метод перемещает ноду $id в родительскую ноду $parentId
public function move($id, $parentId)
{
$node = $this->getNode($id);
DB::query(NULL, 'START TRANSACTION')->execute();
// Удаляем узел (вместе с веткой)
$query =
'DELETE FROM '.Database::instance()->quote_table($this->table).'
WHERE left_key >= '.(int)$node['left_key'].' AND right_key <= '.(int)$node['right_key'];
DB::query(Database::DELETE, $query)->execute();
$width = $node['right_key'] - $node['left_key'] + 1;
// Обновление последующих узлов
$this->modifyNodes((int)$node['right_key'], -$width);
//DB::query(NULL, 'COMMIT')->execute();
}
public function check($thorough=FALSE)
{
$QTblName = Database::instance()->quote_table($this->table);
// Тест 1
$query =
'SELECT id
FROM '.$QTblName.'
WHERE MOD(right_key - left_key, 2) = 0';
$result = DB::query(Database::SELECT, $query)->execute();
if (count($result) != 0)
throw new Exception('Test 1 integrity check failed.');
// Тест 2
$query =
'SELECT id
FROM '.$QTblName.'
WHERE MOD(left_key - level + 2, 2) = 0';
$result = DB::query(Database::SELECT, $query)->execute();
if (count($result) != 0)
throw new Exception('Test 2 integrity check failed.');
// Тест 3
if ($thorough)
{
$query =
'SELECT t1.id, COUNT(t1.id) AS rep, MAX(t3.right_key) AS max_right
FROM
'.$QTblName.' AS t1,
'.$QTblName.' AS t2,
'.$QTblName.' AS t3
WHERE
t1.left_key <> t2.left_key
AND
t1.left_key <> t2.right_key
AND
t1.right_key <> t2.left_key
AND
t1.right_key <> t2.right_key
GROUP BY
t1.id
HAVING
max_right <> SQRT( 4 * rep + 1 ) + 1';
$result = DB::query(Database::SELECT, $query)->execute();
if (count($result) != 0)
throw new Exception('Test 3 integrity check failed.');
}
// Тест 4, проверка level
$query =
'SELECT node.id as id, node.level as level
FROM
'.$QTblName.' AS node,
'.$QTblName.' AS parent
WHERE node.left_key BETWEEN parent.left_key AND parent.right_key
GROUP BY node.id
HAVING COUNT(parent.name) - 1 != level
ORDER BY node.left_key';
$result = DB::query(Database::SELECT, $query)->execute();
if (count($result) != 0)
throw new Exception('Test 4 integrity check failed.');
}
}
..aplicationclassesvalid.php
<?php defined('SYSPATH') or die('No direct script access.');
class Valid extends Kohana_Valid
{
public static function check_id($value, $tablename)
{
$id = (int) $value;
if (! preg_match('/^[a-z_]+$/i', $tablename)) return FALSE;
$count = DB::select(array('COUNT('*')', 'total_count'))
->from($tablename)
->where('id', '=', $id)
->execute()
->get('total_count');
if ($count != 1) return FALSE;
return TRUE;
}
}
..aplicationclassescontrolleraccount.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Account extends Loginverification
{
public $template = 'title';
public function action_index()
{
$data=array();
$myuser = new Model_Myuser();
$data['username'] = $myuser->displayusername(); // в поле username массива data сохранится имя текущего пользователя
if(isset($_POST['btnpassremove']))
{
$oldpass = Arr::get($_POST, 'oldpass', '');
$newpass1 = Arr::get($_POST, 'newpass1', '');
$newpass2 = Arr::get($_POST, 'newpass2', '');
if($myuser->saveNewPass($oldpass, $newpass1, $newpass2))
{
$data['ok']=''; // создание поля ok в массиве data в случае если функции saveNewPass вернулось true(1)
}
else
{
$data['errors']=$myuser->getErrors(); // создание поля errors в массиве и запись ошибок класса myuser в это поле
}
}
$this->template->content=View::factory('accountview', $data); // вывод выбранного вида и массива Data
}
}
..aplicationclassescontrollerajax.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Ajax extends Controller {
public function action_emailunique()
{
$email = Arr::get($_POST, 'email', '');
$myuser = new Model_Myuser();
$res = $myuser->username_unique($email);
echo json_encode(array('result' => $res));
}
public function action_checkOldPass()
{
$oldpass = Arr::get($_POST, 'oldpass', ''); // передача значения поля oldpass в переменную
$myuser = new Model_Myuser(); // объявление класса Model_Myuser
$res = $myuser->checkOldPass($oldpass); // запись true или false в переменную res по результату проверки метода checkOldPass модели myuser
echo json_encode(array('result' => $res)); // вывод в формате json_encode true или false
}
}
..aplicationclassescontrollerauthformer.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Authformer extends Controller_Template // контроллер управления авторизацией пользователей
//расширяется от контроллера Template (внутреннего файла инструкций Kohana)
{
public $template = 'title'; // подключение базового вида
public function action_index() // метод который будет выполнятся по умолчанию
{
$notcapture=Security::xss_clean(Arr::get($_POST, 'authbutton', '')); // берем значение нажатой кнопки входа, сделано это с главной форм ыили с быстрой формы
$captcha = Captcha::instance();
$captcha_image = $captcha->render();
$data=array(); // инициализация пустого массива
$auth = Auth::instance(); // объявление внутреннего класса авторизации
if($auth->logged_in()) // если пользователь авторизован
{
request::initial()->redirect(''); // переадресовать его на главную страницу
}
else // иначе
{
if(isset($_POST['authbutton'])) // если нажата кнопка authbutton
{
$login=Security::xss_clean(Arr::get($_POST, 'login', '')); // в переменную логин записать значение поля логин
$password=Security::xss_clean(Arr::get($_POST, 'password', '')); // в переменную пароль записать значение поля пароль
$capturenka=Captcha::valid(Security::xss_clean(Arr::get($_POST, 'captcha', '')));
if ($notcapture==' ') $capturenka=true; // если нажатие с быстрой формы входа, можно картинку не спрашивать
if(!$capturenka)
{
$data['badimagecode']='';
}
else
{
if($auth->login($login, $password)) // проверка имени и пароля в базе данных таблицы users внутренним методом Kohana
{
$session = Session::instance(); // Создание эземпляра класса Session на основе метода Instance
$auth_redirect = $session->get('auth_redirect',''); // чтение записанного адреса(котнроллера childrenbefore)
$session->delete('auth_redirect'); // удаление сессии
Request::initial()->redirect($auth_redirect); // переадресация пользователя на страницу которую он хотел посетить до авторизации
}
else
{
$data['errors']= ''; // если пользователь не ввел логин и пароль либо ввел но их нету в базе запистаь пустую строку в массив
}
}
}
}
$this->template->content = View::factory('authview', $data)->bind('captcha_image', $captcha_image); // вывод вида
}
public function action_logout() // функция разлогирования
{
$auth=Auth::instance(); // объявление класса авторизации
if($auth->logout()); // выполнение внутреннего метода kohana logout
{
$this->template->content='Вы вышли из системы'; // вывод в качестве контента сообщения
request::initial()->redirect(''); // передаресация на главную страницу
}
}
public function action_form()
{
//Закрываем доступ к данному методу из адресной строки
if($this->request->is_initial())
{
throw new HTTP_Exception_404('File not found!');
}
$this->auto_render = FALSE; //не использовать главный шаблон вида 'title'
$auth = Auth::instance();
if($auth->logged_in())
{
$this->response->body(View::factory('formloginout'));
}
else
{
$this->response->body(View::factory('formloginin'));
}
}
public function action_reg() // функция регистрации
{
$data = array(); // инициализация пустого массива
$captcha = Captcha::instance();
$captcha_image = $captcha->render();
if(isset($_POST['regbutton'])) // елси нажата кнопка regbutton
{
$email =Security::xss_clean(Arr::get($_POST, 'email', '')); // считать значение из поля email
$password = Security::xss_clean(Arr::get($_POST, 'password', '')); // аналогично
$regcodevalue = Security::xss_clean(Arr::get($_POST, 'regcodevalue', ''));
$capturenka=Captcha::valid(Security::xss_clean(Arr::get($_POST, 'captcha', '')));
if(!$capturenka) {$data['badimagecode']='';}
else
{
$register = new Model_Reg(); // объявление модели регистрации
if($register->reg($email, $password, $regcodevalue)) // запись в переменную результата функции reg в модели регистрации
// и отправка на вход функции введенных значений
{
$data['regok'] = ''; // елси функция вернула true создадим пустую строку в поле массива regok
}
else
{
$data['errors'] = $register-> errors; // если функция вернула ошибку валидации записать ошибку в массив
}
}
}
// $view_my_form = View::factory('v_myform')->bind('captcha_image', $captcha_image);
// $this->template->content = $view_my_form;
$this->template->content = View::factory('regview', $data)->bind('captcha_image', $captcha_image); // вывод вида regview и массива data
}
public function action_wantnewpassword()
{
$data = array();
if(isset($_POST['passubmit']))
{
$email = Security::xss_clean(Arr::get($_POST, 'email', ''));
$register = new Model_Reg();
if($register->wantnewpassword($email))
{
$data['ok'] = '';
}
else
{
$data['error'] = '';
}
}
$this->template->content = View::factory('rempassview', $data);
}
public function action_checkreg()
{
$kolan = $this->request->param('id');
$data = array();
$register = new Model_Reg();
if($register->regcomplete($kolan))
{
$data['ok']='';
}
else
{
$data['error']='';
}
$this->template->content = View::factory('completeregisterview', $data);
}
public function action_checkcode($code)
{
$data = array();
$register = new Model_Reg();
if($register->updatepassword($code))
{
$data['ok']='';
}
else
{
$data['error']='';
}
$this->template->content = View::factory('checkcodeview', $data);
}
}
..aplicationclassescontrollercategory.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Category extends Childrenbefore
{
public $template = 'title';
public function action_show()
{
$url = $this->request->param('id'); // запись параметра из url
$data = array(); // инициализация пустого массива data
$tree = new Model_Tree(); // объявление экземпляра класса(model_tree)
$data['category'] = $tree->categoryInfoByUrl($url);
// использование метода categoryInfoByUrl модели tree
// метод определит идентификатор и название категории по введенной пользователем ссылке и присвоит их массиву дата
// --образуя многомерный массив--
if(!$data['category']) // проверка существования категории, если ее нету вывести ошибку 404
{
throw new HTTP_Exception_404('Запрашиваемая категория не найдена');
return;
}
$data['materials'] = $tree->contentСategoryById($data['category']['id']);
// создать поле materials и запистаь туда результат обработки метода contentСategoryById
// contentСategoryById получате значение многомерного массива=идентификатору категории(результата обработки categoryInfoByUrl)
// все материалы введенной категории записываются по описанным методам в массив data поле materials
$this->template->content = View::factory('catview', $data);
}
}
..aplicationclassescontrollermaterials.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Materials extends Childrenbefore
{
public $template = 'title';
public function action_category()
{
$nametrans = $this->request->param('id'); // передача параметра из ссылки, id будет являтся название категории
// причина названия катогории как идентификатора кроется в маршрутизации Kohana файлом bootstrap
$data = array();
$category = new Model_Category('tree');
$material = new Model_Material();
$category_id = $category->getCategoryIdByUrl($nametrans);
if(!$category_id)
{
// если категории нету, то подключить класс HTTP_Exception_404, его путь использования в bootstrap(настройки)
throw new HTTP_Exception_404('Страница не найдена!');
return; // завершить выполнение функции
}
$data['materials'] = $material->getMaterialsByCategory($category_id);
$this->template->content = View::factory('materialsview', $data);
}
public function action_showcontent()
{
$data = array();
$id = $this->request->param('id'); // звпись последней части url в переменную id
$material = new Model_Material(); // создания экземпляра класса модели material
$data = $material->showMaterialById($id); // запись в массив data результата работы метода showMaterialById
//(на который передаем ид материала) модели material
if(!$data) // если дата передана false она становится true и выдает ошибку ненайденной страницы 404
{
throw new HTTP_Exception_404('Запрашиваемая статья не найдена');
return;
}
$this->template->content = View::factory('contentview', $data);
}
}
..aplicationclassescontrollernetprav.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Netprav extends Childrenbefore
{
public $template = 'title';
public function action_index()
{
$this->template->content = View::factory('dontaccess');
}
}
..aplicationclassescontrollerone.php
<?php defined('SYSPATH') or die('No direct script access.');
// контроллер загружаемый по умолчанию ONE(согласно конфигу коханы 'bootstrap') расширяется от контроллера Template(Внутренний файл инструкций Kohana)
class Controller_One extends Controller_Template
{
public $template = 'title'; // загрузка базового вида
public function action_index() // функция по умолчанию
{
$this->template->content = View::factory('titleview'); // добавление к базовому виду вида страницы titleview
}
}
..aplicationclassescontrollerpage.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Page extends Childrenbefore // обычная страница, расширяется от Childrenbefore
{
public $template = 'title'; // испоьзование базового вида страницы
public function action_index() // функция выполняемая по умолчанию
{
$this->template->content = View::factory('pageview'); // вывод вида pageview, добавит вид страницы к базовому
}
}
..aplicationclassescontrollertag.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Tag extends Childrenbefore
{
public $template = 'title';
public function action_showtag()
{
$url = $this->request->param('id'); // $url присваеваем последнее слово из адреса
$data = array(); // инициализация пустого массива
$tag = new Model_Tag(); // создание экземпляра класса модели_tag
$data['tag'] = $tag->tagInfoByUrl($url); // запись в массив дата поле tag результата работы метода tagInfoByUrl
if(!$data['tag']) // елси тег не найден вывести ошибку
{
throw new HTTP_Exception_404('Запрашиваемый тег не найден!');
return;
}
// если тег найден записать в массив data поле materials результат функции contentTagById в моделе tag
$data['materials'] = $tag->contentTagById($data['tag']['id']); // на вход функции приходит найденный идентификатор тега.
// запись материалов по данному тегу в массив data c полем material и вывод в файл вида tagview
$this->template->content = View::factory('tagview', $data);
}
}
..aplicationclassescontrolleradminedit.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Admin_Edit extends Adminverification // главный контроллер, наследуется от Adminverification
{
public $template = 'admin/title'; // основной вид страницы
public function action_index() // функция выполняемая по умолчанию index
{
$data = array(); // пустой массив
$category = new Model_Category('tree'); // соединяемся с таблицей категорий
$data['categories'] = $category->getTree(); // получаем их список
$editmatcat = new Model_Editmatcat; // подключаем модель верстки материалов
if(isset($_POST['iscategory'])) // если категория выбрана
{
unset($data['categories']); // чтоб не отображалить категории когда материал уже выбран
$categoryId = Arr::get($_POST, 'SelectCat', ''); // записать ее идентификатор
if($data['matnames'] = $editmatcat->ShowMatNameList($categoryId)); // вывести имена материалов принадлежащих этой категории
}
if(isset($_POST['delcategory'])) // если категория выбрана
{
$categoryId = Security::xss_clean(Arr::get($_POST, 'SelectCat', '')); // записать ее идентификатор
if(($categoryId == '1')and($categoryId == '-1')and($categoryId == ';')and($categoryId == 'all')) {$data['main']='';}
else
{
if($editmatcat->Delmatsfromcategory($categoryId));
Request::initial()->redirect('admin/edit');
}
}
if(isset($_POST['delmaterial'])) // если категория выбрана
{
$SelectMat = Security::xss_clean(Arr::get($_POST, 'SelectMat', '')); // записать ее идентификатор
$midtemp = ORM::factory('material', array('name'=>$SelectMat)); // наследует ОРМ связь с таблицей материал и вынимаем строчку этого материала
$mid = $midtemp->id;
if(($mid == '1')and($mid == '-1')and($mid == ';')and($mid == 'all')) {$data['mainm']='';}
else
{
if($editmatcat->Delmat($mid));
Request::initial()->redirect('admin/edit');
}
}
if(isset($_POST['ismaterial'])) // если материал выбран
{
unset($data['categories']); // чтоб не отображалить категории когда материал уже выбран
$SelectMat = Arr::get($_POST, 'SelectMat', ''); // вынимаем из селекта русское имя материала
$midtemp = ORM::factory('material', array('name'=>$SelectMat)); // наследует ОРМ связь с таблицей материал и вынимаем строчку этого материала
$mid = $midtemp->id;
Request::initial()->redirect('admin/edit/rewrite/$mid');
//$data['content'] = $editmatcat-Show($categoryId,$SelectMat);
//if($editmatcat->)
}
$this->template->content = View::factory('admin/editview', $data);
}
public function action_rewrite()
{
$mid = Security::xss_clean($this->request->param('id'));
$data = array();
$midtemp = ORM::factory('material', array('id'=>$mid));
$data['mn'] = $midtemp->name; // возьмем имя материала
$data['textik'] = $midtemp->content; // и его текстовое содержание
if(isset($_POST['savem']))
{
$newname = Arr::get($_POST, 'mn', '');
$newtextik = Arr::get($_POST, 'content', '');
if(!$midtemp->loaded())
{
return FALSE;
}
$midtemp->name = $newname;
$midtemp->content =$newtextik;
$midtemp->save();
Request::initial()->redirect('admin/edit');
}
$this->template->content = View::factory('admin/editview', $data);
}
}
..aplicationclassescontrolleradminone.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Admin_One extends Adminverification // главный контроллер, наследуется от Adminverification
{
public $template = 'admin/title'; // основной вид страницы
public function action_index() // функция выполняемая по умолчанию index
{
$category = new Model_Category('tree');
$data['categories'] = $category->getTree();
if(isset($_POST['addcategory']))
{
$categoryName = html::chars( Arr::get($_POST, 'categoryName', ''), false);
$parentId = Arr::get($_POST, 'parentId', '');
$res = $category->catInsert($parentId, array('name'=>$categoryName));
if($res)
{
Request::initial()->redirect('admin');
}
else
{
$data['errors'] = $category->getErrors();
}
}
if(isset($_POST['materialsavebtn'])) // если нажата кнопка materialsavebtn
{
$categoryId = Arr::get($_POST, 'categoryId', ''); // выбранную категорию записать в переменную $categoryId
$content = Arr::get($_POST, 'content', ''); // а содержание текстового поля в $content
$materialname = html::chars(Arr::get($_POST, 'materialname', ''), false);
$tags = html::chars( Arr::get($_POST, 'tagnames', ''), false);
$tagnames = explode(',', $tags); // разбить строку на массив используя запятые
// пример string=one,two,three;
// result[0]=one; result[1]=two; result[2]=three;
//html::chars ($string, false); фильтрация от html тегов в поле
$namevalid = new Model_Namevalid;
if($resu=$namevalid->MatNameValid($materialname)) // если имя материала введено
{
if($resu=$namevalid->TagNameValid($tags))
{
$material = ORM::factory('material'); // то добавим его в базу данных в таблицу materials
$material->addMaterial($categoryId, $content, $materialname);
$matid=$material->ShowIdFromAddMaterial($materialname); // получим идентификтаор добавленного материала
$result = count($tagnames);
for ($x=0; $x<$result;)
{
$tag = new Model_Tag;
$name=$tagnames[$x];
$tag->tagadd($matid, $name);
unset($name);
$x++;
}
Request::initial()->redirect('admin');
}
else
{
$data['errors']=$namevalid->getErrors();
}
// пошлем идентификатор и введенный тег к материалу функции сохранения их в теговые таблицы
// переадрисуем обратно в админку
}
else
{
$data['errors']=$namevalid->getErrors(); // обработка ошибок в имени материала
}
}
$this->template->content = View::factory('admin/adminview', $data);
}
}
..aplicationclassescontrolleradminusers.php
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Admin_Users extends Adminverification // главный контроллер, наследуется от Adminverification
{
public $template = 'admin/title'; // основной вид страницы
public function action_index() // функция выполняемая по умолчанию index
{
$data=array();
$Searchuser = new Model_Searchuser();
if(isset($_POST['SearchGo']))
{
$SearchUsername = Security::xss_clean(Arr::get($_POST, 'username', ''));
if($names=$Searchuser->find($SearchUsername)and($SearchUsername<>''))
{
$data['name']= $names;
$data['findok'] = '';
}
else
{
$data['findno'] = '';
}
}
$data['usercount']=$Searchuser->usercount();
$data['admincount']=$Searchuser->admincount();
$this->template->content = View::factory('admin/usersview', $data);
}
}
..aplicationclassesmodeladdrole.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Addrole extends ORM
{
protected $_table_name = 'roles_users';
}
..aplicationclassesmodelcategory.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Category
{
protected $nstree;
protected $tableName;
protected $errors = array();
public function __construct($tableName)
{
$this->nstree = new NSTree($tableName);
$this->tableName = $tableName;
}
public function getTree()
{
return $this->nstree->getTree();
}
public function catInsert($parentId, $data = array())
{
$data = Arr::extract($data, array('name'));
$text=$data['name'];
$generation = new Model_Generation;
$data['nametrans']=$generation->TanslitGeneration($text);
$vData = $data;
$vData['parentId'] = $parentId;
$nametrans=$data['nametrans'];
$validation = Validation::factory($vData);
$validation->rule('name', 'not_empty');
$validation->rule('name', 'regex', array(':value', '/^[A-я0-9]++$/iD'));
$validation->rule('name', 'min_length', array(':value', '3'));
$validation->rule('name', 'max_length', array(':value', '200'));
$validation->rule('parentId', 'check_id', array(':value', $this->tableName));
$validation->rule('nametrans', array($this, 'unique_url'));
if(!$validation->check())
{
$this->errors = $validation->errors('catErrors');
return FALSE;
}
// Транслит для правильного исопльзования в url
$this->nstree->insert($parentId, $data);
return TRUE;
}
public function getErrors()
{
return $this->errors;
}
public function unique_url($nametrans)
{
return ! DB::select(array(DB::expr('COUNT(nametrans)'), 'total'))
->from($this->tableName)
->where('nametrans', '=', $nametrans)
->execute()
->get('total');
}
public function getCategoryIdByUrl($nametrans)
{
$data = DB::select('id')
->from($this->tableName)
->where('nametrans', '=', $nametrans)
->execute()
->current();
if(!isset($data['id'])) return FALSE;
return $data['id'];
}
}
..aplicationclassesmodeleditmatcat.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Editmatcat
{
public function Delmatsfromcategory($categoryId)
{
$query = DB::delete('materials')
->where('category_id', '=', $categoryId);
$result = $query->as_object()->execute();
$query = DB::delete('tree')
->where('id', '=', $categoryId);
$result = $query->as_object()->execute();
return true;
}
public function Delmat($mid)
{
$query = DB::delete('materials')
->where('id', '=', $mid);
$result = $query->as_object()->execute();
return true;
}
public function ShowMatNameList($category_id)
{
$query = DB::select('name')
->from('materials')
->where('category_id', '=', $category_id);
$result = $query->execute()->as_array();
return $result;
}
}
..aplicationclassesmodelgeneration.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Generation
{
public function PasswordGeneration ($symbols)//кол-во символов в пароле
{
$arr = array('a','b','c','d','e','f',
'g','h','i','j','k','l',
'w','q','s','n','o','v',
't','u','m','x','y','z',
'A','B','C','D','E','F',
'G','H','I','J','K','L',
'W','Q','M','P','R','S',
'U','T','V','I','Y','Z',
'0','2','6','4','5','3',
'7','8','9','1');
//генерируем пасс
$pass = '';
for($a=0; $a<$symbols; $a++)
{
//вычисляем случайный индекс массива
$index = rand(0, count($arr) - 1);
$pass.= $arr[$index];
}
return $pass;
}
public function TanslitGeneration($str)
{
$arr = array(
'А'=>'A','Б'=>'B','В'=>'V','Г'=>'G',
'Д'=>'D','Е'=>'E','Ё'=>'E','Ж'=>'J','З'=>'Z','И'=>'I',
'Й'=>'Y','К'=>'K','Л'=>'L','М'=>'M','Н'=>'N',
'О'=>'O','П'=>'P','Р'=>'R','С'=>'S','Т'=>'T',
'У'=>'U','Ф'=>'F','Х'=>'H','Ц'=>'TS','Ч'=>'CH',
'Ш'=>'SH','Щ'=>'SCH','Ъ'=>'','Ы'=>'YI','Ь'=>'',
'Э'=>'E','Ю'=>'YU','Я'=>'YA','а'=>'a','б'=>'b',
'в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'j',
'з'=>'z','и'=>'i','й'=>'y','к'=>'k','л'=>'l',
'м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r',
'с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'h',
'ц'=>'ts','ч'=>'ch','ш'=>'sh','щ'=>'sch','ъ'=>'y',
'ы'=>'yi','ь'=>'','э'=>'e','ю'=>'yu','я'=>'ya'
);
return strtr($str,$arr);
}
}
..aplicationclassesmodelmaterial.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Material extends ORM // работает с таблицей Materials поскольку метод ORM всегда добавляет в конце букву s.
{protected $_created_column = array('column' => 'createtime', 'format' => TRUE); // внутренний метод kohana
protected $_updated_column = array('column' => 'modtime', 'format' => TRUE); // добавляет в поля время изменения, редактирования
protected $_belongs_to = array( // связь -один к одному- // внутренняя функция kohana // отвечает за то, какой параметр с чем связан с бд
'tree' => array( // название поля --таблицы А--
// 'model' => 'tree', // название связываемой модели()если совпадает с названием массива, то можно не писать строчку)
'foreign_key' => 'category_id', // название связующего поля --таблицы Б--
), );
protected $_has_many = array(
'tag'=>array(
'through'=>'tags_materials', // связь -многие ко многим-
// идентификаторы таблицы tags с tags_id таблицы tags_materials
// не указываются поскольку кохана понимает говорящие названия данных полей
),
);
public function getMaterialsByCategory($category_id)
{
return DB::select()
->from('materials')
->where('category_id', '=', $category_id)
->execute()
->as_array();
}
public function addMaterial($categoryId, $content, $materialname) // получение выбранной категории и введенного контента(текста)
{
$this->category_id = $categoryId;
$this->content = Security::xss_clean($content);
$this->name = Security::xss_clean($materialname); // Security::xss_clean вырежит из содержимого все javascript'ы
// с помощью подключенного модуля purifier(внешняя библиотека)
$this->save(); // запись в базу идентификатора и контента
}
public function ShowIdFromAddMaterial($materialname)
{
$id = ORM::factory('material', array('name'=>$materialname)); // загрузка строки из бд где id = записанному в переменную $userId
$materialname=$id->id; // запишем в переменную $materialname идентификатор найденной строчки только что сохданного материала
return $materialname; // вернем идентификатор в качестве результата функции
}
public function showMaterialById($id) // нам приходит url пользователя(ид материала)
{
$material = ORM::factory('material', array('id'=>$id)); // создание экземпляра класса material для работы с бд (таблица materials)
// ищется и записывается строка с переданным идентификатором
if($material->loaded()) // проверка загруженна ли строка вообще
{
$res = $material->tag->find_all(); // создать массив res в который запистаь действие метода find_all над дополнительным полем tag
foreach($res as $item)
{
$taginfo[] = array('name' => $item->name); // с каждой итерацией цикла записываем
// в массив $taginfo с полями 1,2,...n имена наших материалов
}
$result['content'] = $material->content; // в массив result поле контент записать контент таблицы materials по найденному идентификатору
$result['name'] = $material->name; // аналогично
$result['category'] = $material->tree->name; // получаем доступ к таблице трии и берем от туда название категории с текущим идентификтаором
$result['tag'] = $taginfo; // запись массива taginfo в массив result с полем tag получается многомерный массив
// поля массива $result станут полями массива $data(только если дата не имела полей до этого)
return $result; // функция вернет значения массива result
}
else // если нет, то возвращаем false и заверщаем функцию
{
return FALSE;
}
}
}
..aplicationclassesmodelmyuser.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Myuser extends ORM
{
protected $_table_name = 'users';
protected $errors=array(); // защищенное свойство доступ только у наследников
public function rules()
{
return array(
'password' => array(
array('not_empty'),
array('min_length', array(':value', 7)),
),
'username' => array(
array('not_empty'),
array('min_length', array(':value', 8)),
array('max_length', array(':value', 80)),
array('email'),
array(array($this, 'username_unique')),
),
);
}
public function username_unique($username)
{
$db = Database::instance();
if ($this->id)
{
$query =
'SELECT id
FROM users
WHERE id != '.$this->id.' AND username = '.$db->escape($username);
}
else
{
$query =
'SELECT id
FROM users
WHERE username = '.$db->escape($username);
}
$result = $db->query(Database::SELECT, $query, FALSE)->as_array();
if (count($result) > 0)
{
return FALSE;
}
else
{
return TRUE;
}
}
public function displayusername() // возвращает --имя пользователя-- по методу сравнения с его идентификатором
{
$auth = Auth::instance(); // объявление класса авторизации
$userId = $auth->get_user(); // get_user возвращает идентификатор авторизованного пользователя
$usertemp = ORM::factory('myuser', array('id'=>$userId)); // загрузка строки из бд где id = записанному в переменную $userId
return $usertemp->username; // из этой строки берем имя пользователя
}
public function checkOldPass($oldpass) // проверяет введенный в поле пароль с оригиналом вернет --true или false--
{
$auth = Auth::instance(); // объявление класса авторизации
return $auth->check_password($oldpass); // функция check_password(внутренний метод Kohana) получает введенный пароль и сверяет его с паролем в базе у текущего пользователя
}
public function saveNewPass($oldpass, $newpass1, $newpass2)
{
$vData = array('oldpass' => $oldpass, 'newpass1' => $newpass1, 'newpass2' => $newpass2,); //(для удобства ассоциативен) записываем введенные пароли (старый и новые в массив)
// массив нужен для использования внутреннего метода kohana валидации полей и значений
$validation = Validation::factory($vData); // создание экземпляра класса валидации Kohana и на его вход передается наш ассоциативный массив
$validation->rule('oldpass', 'not_empty'); // внутренняя функция Kohana не дающаяя полю быть пустым
$validation->rule('oldpass', 'alpha_numeric'); // внутренняя функция Kohana допускает только цифры и англ буквы
$validation->rule('oldpass', array($this, 'checkOldPass')); // введенное в поле значение будет отправлено методу checkOldPass выше
$validation->rule('newpass1', 'not_empty');
$validation->rule('newpass1', 'regex', array(':value', '/^[A-z0-9_]++$/iD'));
$validation->rule('newpass1', 'matches', array(':validation', 'newpass1', 'newpass2')); // сравнение newpass1 и newpass2 на идентичность
$validation->rule('newpass1', 'min_length', array(':value', '7'));
$validation->rule('newpass1', 'max_length', array(':value', '16'));
if(!$validation->check()) // запуск внуртеннего метода проверки валидации. Если ошибочно вернет false и превратится в true
{
$this->errors = $validation->errors('catErrors'); // у текущего класса(myuser) в свойство errors (объявлено выше) записываются ошибки по причине которых не прошла валидация
return FALSE; // вернет методу saveNewPass тем самым завершит выполнение
}
$auth = Auth::instance(); // действие описано в комментариях метода displayusername
$userId = $auth->get_user();
$usertemp = ORM::factory('myuser', array('id'=>$userId)); // поиск пользователя с текущим идентификатором
$usertemp->password = $auth->hash_password($newpass1); // запись на место его пароля нового в зашифрованном виде
$usertemp->save(); // сохранение действия записи
return TRUE; // прекращение выполнения функции и передача ей true(1)
}
public function getErrors()
{
return $this->errors; // вовращении функции существующих ошибок в model Myuser
}
}
..aplicationclassesmodelnamevalid.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Namevalid
{
protected $errors=array();
public function MatNameValid($materialname)
{
$vData = array('materialname' => $materialname,);
$validation = Validation::factory($vData);
$validation->rule('materialname', 'not_empty');
$validation->rule('materialname', 'min_length', array(':value', '3'));
$validation->rule('materialname', 'max_length', array(':value', '20'));
if(!$validation->check())
{
$this->errors = $validation->errors('addmatErrors');
return FALSE;
}
return TRUE;
}
public function TagNameValid($tags)
{
$vData = array('tags' => $tags,);
$validation = Validation::factory($vData);
$validation->rule('tags', 'not_empty');
if(!$validation->check())
{
$this->errors = $validation->errors('addmatErrors');
return FALSE;
}
return TRUE;
}
public function getErrors()
{return $this->errors;}}
..aplicationclassesmodelreg.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Reg
{
public function getErrors() // функция обработки ошибок валидации
{
return $this->errors; // функция вернет записанную ошибку
}
public function reg($email, $password, $regcodevalue, $data = array()) // получаем введенные значения и пустой массив
{
$data['password'] = $password; // в массив data поле пароля записываем введенный пароль
$data = Arr::extract($data, array('password')); // извлекаем пароль из массива
$validation = Validation::factory($data); // объявляем метод вализации переменной data
$validation->rule('password', 'not_empty');
$validation->rule('password', 'regex', array(':value', '/^[A-z0-9_]++$/iD'));
$validation->rule('password', 'min_length', array(':value', '7'));
$validation->rule('password', 'max_length', array(':value', '16'));
if(!$validation->check())
{
$this->errors = $validation->errors('catErrors');
return FALSE;
}
$regcode = new Model_Regcode();
$myuser = new Model_Myuser();
$regcode->code = $regcodevalue;
try
{
$regcode->check(); // метод чек проверяет параметры на правила
}
catch(ORM_Validation_Exception $e)
{
$this->errors = $e->errors('validation');
return FALSE;
}
// создание пользователя
$myuser->username = $email;
$myuser->email = $email;
// берем сгенерированный пароль в размере 16 символов
$generation = new Model_Generation();
$key = $genpass = $generation->PasswordGeneration(16);
// хэшируем данный пароль для дальнейшего его поступления в бд
$auth = Auth::instance();
$myuser->password = $auth->hash_password($password);
try
{
if(isset($email)and(isset($password)))
{
$myuser->save();
// узнаем id пользователя
$usertemp = ORM::factory('myuser', array('username'=>$email));
$adduserid = $usertemp->id;
// для проверки ида нового юзера на экране
// var_dump($adduserid);
// exit;
// Создаем роли
$addrole = new Model_Addrole();
$addrole->user_id = $adduserid;
if ( ($key!=0)or($key!='-1')or($key!=2) )
{
$addrole->role_id = $key;
}
$addrole->save();
// Диактивация регистрационного кода
$regcode->disactive_code($regcodevalue, $adduserid);
// Отправка эл.почты
$sendtomail = new Model_Sendtomail();
$to = $email;
$from = 'skutorlike@mail.ru';
//$subject = 'Подтверждение регистрации в КГК';
/* $message = 'Ваш логин: $email, Ваш пароль: $password
<br>
<br>Ссылка для подтверждения аккаунта: <a href='http://localhost/authformer/checkreg/$key'> ПОДТВЕРДИТЬ </a>';
*/
$subject = Kohana::message('emailthemes/register','subject');
$data = array ('email' => $email,'password' => $password, 'key' => $key );
$message = View::factory('emailbody/register',$data);
$sendtomail->sendemail($to,$from,$subject,$message, true);
unset($key);
unset($genpass);
return TRUE;
}
}
catch(ORM_Validation_Exception $e)
{
$this->errors = $e->errors('validation');
return FALSE;
}
}
public function regcomplete($kolan)
{
if(($kolan!='-1')or($kolan!='0')or($kolan!='all')or($kolan!='1'))
{
$result = DB::select()
->from('roles_users')
->where('role_id', '=', Security::xss_clean($kolan))
->execute();
if (count($result) == 0)
{
return false;
throw new Exeption('Данный ключ не существует');
}
else
{
$query = DB::update('roles_users')
->set(array('role_id' => '1'))
->where('role_id', '=', $kolan);
$query->execute();
return true;
}
}
}
public function updatepassword($code)
{
$usertemp = ORM::factory('myuser', array('rempass'=>$code));
if(!$usertemp->loaded())
{
return FALSE;
}
$generation = new Model_Generation();
$genpass = $generation->PasswordGeneration(8);
//Хеширование пароля
$auth = Auth::instance();
$usertemp->password = $auth->hash_password($genpass);
//Очистка кода восстановления
$usertemp->rempass = NULL;
$usertemp->save();
$sendtomail = new Model_Sendtomail();
//Отправка эл. почты
$email = $usertemp->username;
$from = 'skutorlike@mail.ru';
//$subject = 'Авторизационные данные обновлены';
$subject = Kohana::message('emailthemes/rememberpasswordcomplete','subject');
//$message = 'Ваш логин: $email Ваш пароль: $genpass';
$data = array ('email' => $email,'genpass' => $genpass );
$message = View::factory('emailbody/rememberpasswordcomplete',$data);
$sendtomail->sendemail($email, $from, $subject, $message, TRUE);
return TRUE;
}
public function wantnewpassword($email)
{
$usertemp = ORM::factory('myuser', array('username'=>$email));
if(!$usertemp->loaded())
{
return FALSE;
}
$generation = new Model_Generation();
$genpass = $generation->PasswordGeneration(8);
$usertemp->rempass = $genpass;
$usertemp->save();
$sendtomail = new Model_Sendtomail();
//Отправка эл. почты
$from = 'skutorlike@mail.ru';
//$subject = 'Восстановление пароля';
$subject = Kohana::message('emailthemes/rememberpassword','subject');
//$message = 'Перейдите по ссылке <a href='http://localhost/authformer/checkcode/$genpass'>Восстановить пароль</a>';
$data = array ('genpass' => $genpass);
$message = View::factory('emailbody/rememberpassword',$data);
$sendtomail->sendemail($email, $from, $subject, $message, TRUE);
return TRUE;
}
}
..aplicationclassesmodelregcode.php
<?php defined('SYSPATH') or die('No direct script access.');
// валидация параметра -код-
class Model_Regcode extends ORM
{
// protected $_table_name = 'users'
public function rules()
{
return array(
'code' => array(
array('not_empty'),
array(array($this, 'bad_code')),
),
);
}
public function bad_code($code)
{
$regcodetemp = ORM::factory('regcode', array('code'=>$code));
// создание временной переменной регкодетемп хранящий введенное значение и сверка тождественности с параметром регкод который зависит от таблицы с кодами
if($regcodetemp->loaded())
{
if($regcodetemp->user_id == NULL)
// если код не занят еще ни 1 пользователем то вернуть функции тру если занят вернуть фолс.
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
public function disactive_code($code, $user_id)
{
$regcodetemp = ORM::factory('regcode', array('code'=>$code));
$regcodetemp->user_id = $user_id;
$regcodetemp->save();
}
}
..aplicationclassesmodelsearchuser.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Searchuser
{
public function find($SearchUsername)
{
$query = DB::select('username')
->from('users')
->where('username', 'like', ('%'.Security::xss_clean($SearchUsername)).'%');
$result = $query->execute()->as_array();
return $result;
}
public function usercount()
{
$result = DB::select('id')
->from('users')
->execute();
return count($result);
}
public function admincount()
{
$result = DB::select('role_id')
->where('role_id', '=', '2')
->from('roles_users')
->execute();
return count($result);
}
}
..aplicationclassesmodelsendtomail.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Sendtomail
{
public function sendemail($to,$from,$subject,$message, $html)
{
try
{
$count = Email::send($to,$from,$subject,$message, $html);
return TRUE;
}
catch (Exception $e)
{
echo $e->getMessage();
return false;
}
}
}
..aplicationclassesmodeltag.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Tag extends ORM
{
protected $_has_many = array( // связь -многие ко многим-
'material' => array(
'model' => 'material',
'through' => 'tags_materials', //обязательный параметр для этой связи // связь между таблицей -materials- и -tags- будет осуществлятся через таблицу -tags_materials-
'foreign_key' => 'tag_id', // ключевое поле текущей таблицы
'far_key' => 'material_id', // ключевое поле к таблице которой привязываем
),
);
public function tagadd($matid, $name)
{
$url=$_SERVER['HTTP_ORIGIN']; // определяем доменное имя сайта до первого слеша(http://hello.ru)
$this->name = Security::xss_clean($name); // в таблицу tags поле name записываем тег
// проверим заодно введенные теги, чтоб были без скриптов и др гадостей
$this->url = ''; // ссылка тега изначальна как пустая, поскольку у него еще нету идентификатора
$this->save(); // записываем в таблицу и получаем идентификатор
$tagid=$this->id; // берем данный идентификатор в переменную tagid
$TagsMaterial = new Model_Tagsmaterial; // объявляем класс для работы с бд(нужно для таблицы tags_materials)
$TagsMaterial->tag_id=$tagid; // записываем в таблицу tags_materials идентификтаор нашего тега
$TagsMaterial->material_id = $matid; // записываем в эту же таблицу идентификатор тега к этому материалу
$TagsMaterial->save(); // сохраняем в таблицу
$tags = ORM::factory('tag', array('id'=>$tagid)); // находим записанную строчку у таблицы tags
$this->url = '$url/materials/showcontent/$tagid'; // теперь заполним нашу пустую ссылку ссылкой на идентификтаор материала
$this->save(); // произведем сохранение записи
return;
}
public function tagInfoByUrl($url)
{
$tree = ORM::factory('tag', array('url'=>$url));
// создания класса работы с бд и поиск в поле url нашего введенного url
if($tree->loaded()) // если загружена хоть 1 строчка
{
$result['id'] = $tree->id; // присвоить массиву result с полем ид и name найденный идентификатор и имя
$result['name'] = $tree->name;
return $result; // в результатае функция вернет массив result
}
else
{
return FALSE;
}
}
public function contentTagById($id) // пришел ид набранного тега
{
$tag = ORM::factory('tag', array('id'=>$id)); // ищем есть ли он в таблице tag в поле id
if($tag->loaded()) // если есть
{
$result = array(); // создаем пустой массив
$res = $tag->material->find_all(); // создание дополнительного поля material и
// поиск всех материалов рлдходящих к тегу с имеющимся идентификатором
foreach($res as $item) // заполнение массива result поматериально с каждым шагом цикла
{
$result[] = array('id' => $item->id, 'content' => $item->content, 'name' => $item->name);
}
return $result; // функция вернет массив result
}
else
{
return FALSE;
}
}
}
..aplicationclassesmodeltagsmaterial.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Tagsmaterial extends ORM
{
protected $_table_name = 'tags_materials';
}
..aplicationclassesmodeltree.php
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Tree extends ORM
{
protected $_table_name = 'tree';
protected $_has_many = array( // метод связи -один ко многим-
'materials' => array( // какое доп. свойство хотите
'model' => 'material', // с какой моделью хотим соединится
// (модель соостветственно должна расширятся от орм)
'foreign_key' => 'category_id', // название связываемого поля
),
);
public function categoryInfoByUrl($url)
{
$tree = ORM::factory('tree', array('nametrans'=>$url)); // создается экземпляр класса orm для работы с бд
// из таблицы tree достается строчка в которой поле nametrans совпадает со значением переменной $url
if($tree->loaded()) // проверка загруженной строки
{
$result['id'] = $tree->id; // если строка найдена и загружена то
$result['name'] = $tree->name; // присвоем массиву result идентификтаор и имя категории
return $result; // все успешно метод возвращает массив с полями ид и имя категории
}
else // если строк ане загруженна функция вернет false
{
return FALSE;
}
}
public function contentСategoryById($id)
{
$tree = ORM::factory('tree', array('id'=>$id)); // создается экземпляр класса orm для работы с бд
// из таблицы tree достается строчка в которой поле url совпадает со значением переменной $url
if($tree->loaded())// есть ли такой идентификатор в таблице
{
$result = array(); // пустой массив $result
$res = $tree->materials->find_all(); // загрузка всех материалов данной категории в массив $res
foreach($res as $item) // прокрутка материалов и понумерованная запись в массив $result
{
$result[] = array('id' => $item->id, 'content' => $item->content, 'name' => $item->name);
}
return $result;
}
else
{
return FALSE;}}}
..aplicationclassesmodeluser.php
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_User extends Model_Auth_User {
public function rules()
{
return array(
'username' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 32)),
),
'password' => array(
array('not_empty'),
),
'email' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 127)),
array('email'),
),
);
}
}
..aplicationviews404view.php
<style>
*body{
margin: 0;
padding: 0;}
#wrapper{
width: 500px;
margin: 0 auto;}
#e404e{
margin: 0 auto;
padding: 100px 0;
text-align: center;
border: none;}
</style>
<div id='wrapper'>
<div id='e404e'>
<p> Ошибка - № 404.
<br /> Страница не найдена!
</p>
<a href='/'>
<img src='/img/404.gif' alt='error404 - страница не найдена' border='0' />
</a>
<br />
<?php echo $message ?>
</div>
</div>
..aplicationviewsaccountview.php
<!--Вызов отображение формы логина-->
<?
$request = Request::factory('authformer/form/1');
$response = $request->execute();
echo $response;
?>
<!-- / Вызов отображение формы логина-->
<!-- Вывод сообщения об успешной смене пароля -->
<?if(isset($ok)) // если существует $ok
{?>
<p style='text-align:center; color:green;'>
Новый пароль успешно сохранен
</p>
<?}?>
<!-- /Вывод сообщения об успешной смене пароля -->
<!-- Вывод ошибок валидации при сохранении нового пароля -->
<? if(isset($errors) // усли существует $errors
){?>
<?foreach($errors as $item){?>
<p style='color:red'><?=$item?></p>
<?}?>
<?}?>
<!-- / Вывод ошибок валидации при сохранении нового пароля -->
<h2>Личный кабинет</h2>
<p>Здравствуйте, <?=$username?>.</p>
<p><b>Смена пароля:</b> <input type='checkbox' id='showpassbtn' /><label for='showpassbtn'> Не прятать пароль за звездочки</label></p>
<form action='' method='post'>
<table class='changepassword'>
<tr>
<td style='text-align: right'>Старый пароль:</td>
<td><input type='password' name='oldpass' id='oldpass' /></td>
<td>
<span style='display: none' id='ok'><img src='/img/true.png' title='Старый пароль введен правильно' alt='Старый пароль введен правильно' /></span>
<span style='display: none' id='error'><img src='/img/false.png' title='Ошибка в старом пароле' alt='Ошибка в старом пароле' /></span>
</td>
</tr>
<tr>
<td style='text-align: right'>Новый пароль:</td>
<td><input type='password' name='newpass1' id='newpass1' /></td>
<td> </td>
</tr>
<tr>
<td style='text-align: right'>Повторите новый пароль:</td>
<td><input type='password' name='newpass2' id='newpass2' /></td>
<td>
<span style='display: none' id='newpassmatchesok'><img src='/img/true.png' title='Пароли совпадают' alt='Пароли совпадают' /></span>
<span style='display: none' id='newpassmatcheserror'><img src='/img/false.png' title='Пароли несовпадают' alt='Пароли несовпадают' /></span>
</td>
</tr>
<tr>
<td> </td>
<td><input type='submit' value='Сохранить пароль' name='btnpassremove' /></td>
</tr>
</table>
</form>
<script type='text/javascript'>
function checkOldPass()
{
var oldpass = $('#oldpass').val(); // создается перемеррная oldpass куда заносится значение поля с id=oldpass
$.ajax({ // запрос на отправку данных
type: 'POST', // метод скрытый
data: 'oldpass=' + oldpass, // в контейнер oldpass запишется значение переменной oldpass
url: '/ajax/checkOldPass', // куда отправится
dataType: 'json',
success: function(data)
{
if(data.result) // если функция action_checkOldPass контроллера Ajax вернула true или false
{
$('#ok').css('display','inline');
$('#error').css('display','none');
}
else
{
$('#error').css('display','inline');
$('#ok').css('display','none');
}
}
})
}
function showPass()
{
var checked = $('#showpassbtn').attr('checked'); // переменная checked
if(checked == 'checked') // если галка стоит
{
document.getElementById('oldpass').type = 'text'; // поле с идентификатором oldpass становится типа text
document.getElementById('newpass1').type = 'text';
document.getElementById('newpass2').type = 'text';
}
else
{
document.getElementById('oldpass').type = 'password';
document.getElementById('newpass1').type = 'password';
document.getElementById('newpass2').type = 'password';
}
}
function matchesPass()
{
if($('#newpass1').val() == $('#newpass2').val()) // сравнение newpass1 поля с newpass2 полем
{
$('#newpassmatchesok').css('display','inline');
$('#newpassmatcheserror').css('display','none');
}
else
{
$('#newpassmatcheserror').css('display','inline');
$('#newpassmatchesok').css('display','none');
}
}
$(document).ready(function(){
$('#oldpass').blur(checkOldPass);
$('#showpassbtn').click(showPass);
$('#newpass2').keyup(matchesPass);
});
</script>
..aplicationviewsauthview.php
<?php
if (isset ($errors))
{
echo '<p style='text-align:center; color:red'/>
Неверный логин или пароль. </p>';
}
if (isset ($badimagecode))
{
echo '<p style='text-align:center; color:red'/>
Неверно введен код с картинки. </p>';
}
?>
<form action='' method='post'>
<table class='login'>
<tr>
<th colspan='2' style='text-align:center'><h2> Авторизация </h2> </th>
</tr>
<tr>
<td>Логин: </td>
<td> <input type='text' name='login' /> </td>
</tr>
<tr>
<td>Пароль: </td>
<td> <input type='password' name='password' /> </td>
</tr>
<script>
function reload(){
id=Math.floor(Math.random()*1000000);
$('img.captcha').attr('src','/captcha/default?id='+id);
}
</script>
<tr>
<td>
<?=$captcha_image?>
<img alt='Обновить код' onclick='reload()' src='/img/refresh.gif' style='cursor:pointer; vertical-align: super;' title='Обновить код' />
</td>
<td>
<input type='text' name='captcha' />
</td>
</tr>
<tr>
<th colspan='2' style='text-align:right'> <input type='submit' value='Войти' name='authbutton' style='width: 163px; height: 30px;' /> </th>
</tr>
<tr>
</tr>
</table><br />
<a style='color: black; margin-left: 60px; padding: 10px;' href='authformer/wantnewpassword'> Забыл пароль </a>
<a style='color: black; padding: 10px;' href='authformer/reg'> Регистрация </a>
</form>
..aplicationviewscatview.php
<style>
#catview a{
color:#333;
font-weight: bold;
font-size: 16px;
font-style: normal; }
#catview a:hover{
color:#000;
font-style: italic; }
#content_container{
background-image: none;}
</style>
<div id='catview'>
<h2>Содержимое категории <?=$category['name']
// в контроллере категорий
// $data['category'] = $tree->categoryInfoByUrl($url)
?></h2>
<ul style='padding: 30px;'>
<? if(count($materials)) // проверка есть ли материалы в категории
{
foreach($materials as $item)
{?>
<li>
<p></p><a href='/materials/showcontent/<?=$item['id']?>'><? echo htmlspecialchars($item['name'])?></a></p>
<p><?=$item['content']?></p>
</li>
<?}?>
<?}else{?>
<p>В выбранной категории нет материалов</p>
<?}?>
</ul>
</div>
..aplicationviewscheckcodeview.php
<?php
echo
'<p style='text-align:center; color:green;'> Введите адрес Вашей электронной почты: </p>';
if(isset($error))
{
echo
'<p style='text-align:center; color:green;'> Данный адрес не существует. </p>';
}
if(isset($ok))
{
echo
'<p style='text-align:center; color:red;'> Зайдите и проверьте Вашу почту </p>';
}
?>
..aplicationviewscompleteregisterview.php
<script>
function url()
{
setTimeout('location.href='/authformer';', 4000);
}
</script>
<body onload='url()'>
<?php
echo
'<p style='text-align:center; color:green;'> ПРОВЕРКА ПОДЛИННОСТИ РЕГИСТРАЦИОННЫХ ДАННЫХ: </p>';
if(isset($error))
{
echo
'<p style='text-align:center; color:red;'> Код подтверждения регистрации недействителен! </p>';
}
if(isset($ok))
{echo
'<p style='text-align:center; color:green;'> Регистрация успешно подтверждена! </p>'; }?>
..aplicationviewscontentview.php
<style>
body{
margin: 0;
padding: 0;}
h3{font-weight: normal;}
#content_container{background-image: none;}
#links a{
color: #333;
font-style: normal;
margin: 0;
padding: 0;}
#links{
margin: 0;
padding: 0;
line-height: normal;}
</style><div id='links'><ul style='padding: 30px;'><li>
Категория: <b><?=$category?></b></li><li>Материал: <b><?=$name?></b></li><br />
<b>Содержимое статьи:</b> <? print $content?></ul><ul><p>
<b>Статье присвоены следующие теги: </b><br /><? if(isset($tag))
{ foreach($tag as $item){?><li> <?= $item['name']?></li><?} }?></p></ul></div>
..aplicationviewsdontaccess.php
<p style='text-align: center;'> У Вас недостаточно доступа для просмотра данной страницы! </p>
..aplicationviewsformloginin.php
<script type='text/javascript'>
function OpenSlider() // при нажатии вход
{
$('#slider-in').animate({ height: '200px' }); // плавное изменение высоты от 0 до 170пх
$('#login').focus(); // фокусировка поля с ид логин
$('#open-div').toggle(); // toogle изменяет с видемого на невидимый
$('#close-div').toggle(); // наоборот с невидимого сделал видимым
return false; // запрет перехода по ссылке -Войти-
}
function CloseSlider()
{
$('#slider-in').animate({ height: '0' }); // наоборот первому
$('#open-div').toggle();
$('#close-div').toggle();
return false;
}
$(document).ready(function(){ // прочетсь сначала весь документ
$('#open-button').click(OpenSlider); // запустить функцию открытьслайдер 1-ая
$('#close-button').click(CloseSlider); // в случае нажатия на скрыть с ид клос-батом запустить функцию клос слайдер
});
</script>
<div id='slider'>
<div id='slider-in'>
<form action='/authformer' method='post'>
<p id='ptext'>Логин:</p>
<input type='text' name='login' id='login' />
<p id='ptext'>Пароль:</p>
<input type='password' name='password' /><br />
<p class='btmimg' ><input type='image' name='authbutton' value=' ' style='width: 110; height: 40; outline: hidden; border: none;' /></p>
</form>
<p><a href='/authformer/reg'>Быстрая регистрация</a></p>
<p><a href='authformer/wantnewpassword'> Забыл пароль </a> </p>
</div>
<div id='open-div'><a href='#' id='open-button'>Вход</a></div>
<div id='close-div' style='display:none'><a href='#' id='close-button' ><img src='/img/exit.png' width='14px' height='14px' alt='hide' align='right' /> </a></div>
</div>
..aplicationviewsformloginout.php
<div id='slider'><a href='/authformer/logout'>Выйти</a></div>
..aplicationviewsmaterialsview.php
<style>#content_container{background-image: none;}</style>
<?foreach($materials as $item){?>
<p><?=($item['content'])?></p>
<?}?>
..aplicationviewspageview.php
<p style='text-align: center;'> Это обычная страница! </p>
..aplicationviewsregview.php
<?php
if(isset($regok))
{
echo
'<p style='text-align:center; color:green;'> Регистрация прошла успешно. Проверьте Ваш E-Mail. </p>'; ?>
<script>function url() { setTimeout('location.href='/authformer';', 5000); }</script>
<body onload='url()'><?php } if(isset($errors)){foreach ($errors as $item){
echo '<p style='text-align:center; color:red;'> Ошибка $item </p>';} }
if (isset ($badimagecode)){
echo '<p style='text-align:center; color:red'/>Неверно введен код с картинки. </p>';}?>
<form action='' method='post'><table class='login'><tr><th colspan='2' style='text-align:center'><h2> <? echo 'Регистрация'; ?> </h2> </th></tr><tr>
<td>E-Mail: </td><td> <input type='text' name='email' /> </td>
</tr><tr><tr><td>Пароль: </td><td> <input type='password' name='password' /> </td></tr><td>Код регистрации(инвайт): </td><td> <input type='text' name='regcodevalue' /> </td></tr><script>
function reload(){id=Math.floor(Math.random()*1000000);
$('img.captcha').attr('src','/captcha/default?id='+id);}</script>
<tr> <td><?=$captcha_image?>
<img alt='Обновить код' onclick='reload()' src='/img/refresh.gif' style='cursor:pointer; vertical-align: super;' title='Обновить код' />
</td><td><input type='text' name='captcha' /></td></tr> <tr>
<th colspan='2' style='text-align:right'> <input type='submit' value='Зарегистрироваться' name='regbutton' style='width: 163px; height: 30px;' /> </th></tr></table> </form>
..aplicationviewsrempassview.php
<?php
echo '<p style='text-align:center; color:green;'> Введите адрес Вашей электронной почты: </p>';
if(isset($error))
{echo '<p style='text-align:center; color:green;'> Данный адрес не существует. </p>'; }
if(isset($ok))
{echo '<p style='text-align:center; color:red;'> Зайдите и проверьте Вашу почту </p>'; }?>
<form action='' method='post'><table class='login'><tr>
<th colspan='2' style='text-align:center'><h2> Восстановление забытого пароля </h2> </th></tr><tr><td>E-Mail: </td><td> <input type='text' name='email' id='email' />
<span id='trueimg' style='display: none;'><img src='/img/true.png' alt='true' /></span>
<span id='falseimg' style='display: none;'><img src='/img/false.png' alt='false' /></span> </td></tr><tr><th colspan='2' style='text-align:right'> <input type='submit' value='Восстановить' name='passubmit' style='width: 163px; height: 30px;' /> </th>
</tr></table></form>
<script type='text/javascript'>
function runajax(){var email = $('#email').val();
$.ajax({type: 'POST',data: 'email=' + email,url: '/ajax/emailunique',dataType: 'json',success: function(data){
if(!data.result){$('#trueimg').css('display','inline');$('#falseimg').css('display','none');}
else{$('#falseimg').css('display','inline');$('#trueimg').css('display','none');}}})}
$(document).ready(function(){$('#email').blur(runajax);});</script>
..aplicationviewstagview.php
<h2>Содержимое категории <?=$tag['name']?></h2><ul style='padding: 30px;'>
<?if(count($materials)) {foreach($materials as $item){?><li>
<p><a href='/materials/showcontent/<?=$item['id']?>'><?=$item['name']?></a></p>
<p><?=$item['content']?></p></li><?}?><?}else{?>
<p>В выбранной категории нет материалов</p><?}?></ul>
..aplicationviewstitle.php
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
<title>Skutor - Kohana Framework</title>
<link href='/css/stylesheet.css' rel='stylesheet' type='text/css' />
<script type='text/javascript' src='/js/jquery-1.7.1.js' ></script>
<script type='text/javascript' src='/ckeditor/ckeditor.js'></script>
</head><body>
<div id='top_bar_black'> <div id='logo_container'> <div id='logo_image'> </div> <div id='nav_block'> <div class='nav_button'><a href='/'>Главная </a></div><div class='nav_button'><a href='/category/show/biografiya'> Биография автора</a></div><div class='nav_button'><a href='/category/show/dizayn'> Дизайн-проект</a></div><div class='nav_button'><a href='/category/show/dvijok'> Движок-проект</a></div><div class='nav_button'><a href='/category/show/kontaktyi'> Контакты </a></div> </div></div> </div><div id='content_container'><?php echo $content ?></div><div id='clear'></div><div id='bottom_bar_black'> <div id='main_container'></div> </div><div id='copywriteblock'> <a href='mailto:skutorlike@mail.ru'>© Автор сайта: skutor </a></div></body></html>
..aplicationviewstitleview.php
<?php $request = Request::factory('authformer/form'); // запуск метода form в контроллере authformer
$response = $request->execute(); echo $response;?>
<div id='header'> <div class='header_content_mainline'> Программный Комплекс Управления Сайтом</div><div id='header_content_tagline'>The System Software Control of Website with Kohana Framework </div></div><div id='header_lower'> <div id='header_content_boxline'>'Движок'<div id='header_content_boxcontent'><br />Вообще-то, движок, это жаргонное выражение, правильное название - программный комплекс управления сайтом. Подобная система управления может состоять из множества небольших модулей (т.е. несколько маленьких программ), которые объединены в общую систему.Наиболее часто встречается аббревиатура CMS - Content Managment System - Система Управления Контентом.Движки, в подавляющем большинстве случаев, программируются на языке PHP, тем не менее, возможно применение других языков, всё зависит от программиста и возможностей хостинга. В любом случае, движок всегда работает в связке с базой данных MySQL (базы данных так же должны поддерживаться хостером).<br /><b>Принцип действия:</b>Для начала, обратимся к работе обычного сайта. Как происходит открытие веб-страницы? В строку браузера вводится адрес и открывается соответствующая ему страница, из тех, которые лежат на сервере. Если адрес введён неправильно, то получим ошибку 404 (на сервере такая страница не обнаружена). Как происходит открытие страницы на сайте, которой функционирует с помощью CMS? Страниц, как таковых, на сервере нет. Есть база данных, в которой находится текстовая информация и есть программа, которая работает с этой базой данный (тот самый движок). В строку браузера вводится адрес, в соответствии с адресом, программа «выдёргивает» из базы определённый кусок текста, вставляет его в заранее заданный дизайн и показывает посетителю. На все эти действия уходят доли секунды.Таким образом, страница будет генерироваться столько раз, сколько её будут запрашивать посетители.Итак, мы пришли к определениям статической и динамической страницы.Статическая страница - находится на сервере в виде отдельного файла и отображается при каждом запросе.Динамическая страница - фактически, её не существует, т.е. она собирается заново при каждом новом запросе посетителя сайта.</div></div> </div>
<div id='header_lower'> <div id='header_content_boxline'>Kohana</div> <div id='header_content_boxcontent'><br /><b> Kohana </b> -- это HMVC PHP5 веб фреймворк, предоставляющий средства для разработки web-приложений. Благодаря своей каскадной файловой системе, большому количеству встроенных утилит и последовательному API, он идеально подходит для решения большинства задач, а высокая скорость выполнения и обширные возможности профилирования позволяют ускорить разработку и использовать менее мощные ресурсы для содержания конечного продукта.<p><ul><b>Почему именно Kohana?</b><li>Высокая скорость выполнения</li><li>Использование всех возможностей PHP5</li><li>Большое количество встроенных инструментов, в том числе ORM и Database</li><li>Малые системные требования</li><li>Средства профилирования и отладки</li><li>Поддержка UTF-8 и I18N</li></ul></p>Первоначальная версия Kohana была известна как Blue Frame и являлась форком CodeIgniter. Затем разработчики посчитали нужным переименовать свой проект, и с версии 2.0 за фреймворком укрепилось название Kohana. В сентябре 2009 года выходит новая версия, 3.0, в которой был полностью переписан код, добавлено множество нововведений, а также увеличена скорость по отношению к Kohana 2.</div></div>
..aplicationviewsemailbodyregister.php
<?php echo'Ваш логин: $email, Ваш пароль: $password <br><br>Ссылка для подтверждения аккаунта: <a href='http://localhost/authformer/checkreg/$key'> ПОДТВЕРДИТЬ </a>';?>
..aplicationviewsemailbodyrememberpassword.php
<?php echo 'Перейдите по ссылке
<a href='http://localhost/authformer/checkcode/$genpass'>восстановить пароль</a>'; ?>
..aplicationviewsemailbodyrememberpasswordcomplete.php
<?php echo 'Ваш логин: $email Ваш пароль: $genpass'; ?>
..aplicationviewsadminadminview.php
<p><h3>Страница управления материалами</p></h3><div style='padding: 50px;'>
<!-- Вывод ошибок валидации при сохранении нового пароля -->
<? if(isset($errors) // если существует $errors){?><?foreach($errors as $item){?>
<p style='color:red'><?=$item?></p><?}?><?}?>
<!-- / Вывод ошибок валидации при сохранении нового пароля -->
<div><form method='post' action=''><h3 style='font-size: 16px; font-family: Verdana;'>Создать категорию: </h3><select name='parentId'>
<?foreach($categories as $item) {?><option value='<?=$item['id']?>'><?=str_repeat(' ', 4*$item['level']).htmlspecialchars($item['name'])?></option><?}?></select>
<input type='text' name='categoryName' /><input type='submit' value='Добавить' name='addcategory' /></form></div>
<h3 style='font-size: 16px; font-family: Verdana;'>Добавить материал: </h3>
<form action='' method='post' style='width: 900px;'><div><select name='categoryId'>
<?foreach($categories as $item) {?><option value='<?=$item['id']?>'><?=str_repeat(' ', 4*$item['level']).htmlspecialchars($item['name'])?></option>
<?}?></select><span>Название материала: <input type='text' name='materialname' />
<span style='padding: 0 10px;'>
Теги к статье(через запятую): <input type='text' name='tagnames' alt='Введите теги к материалу через запятую!' />
</div></span></span><textarea name='content' id='editor'></textarea>
<input type='submit' value='Сохранить' name='materialsavebtn' /></form></div>
<script type='text/javascript'>
CKEDITOR.replace( 'editor' ); // CKEDITOR подключить к текстовому полю с идентификатором editor
</script></div>
..aplicationviewsadmineditview.php
<p><h3>Страница редактирования категорий и материалов</h3></p>
<div style='padding: 50px;'><div>
<?php if(isset($main)) echo 'Главную категорию запрещено удалять!'; ?>
<?php if(isset($mainm)) echo 'Удаление материала запрещено!'; ?>
<form action='' method='post'><?if(isset($categories)){?><?='<select name='SelectCat'>';foreach($categories as $item) {?><option value='<?=$item['id']?>'><?=str_repeat(' ',4*$item['level']).htmlspecialchars($item['name'])?></option><?}?></select>
<input type='submit' value='Выбрать категорию' name='iscategory' />
<input type='submit' value='Удалить категорию' name='delcategory' /><?}?></form>
<form method='post' action=''><? if(isset($matnames)){?><?='<select name='SelectMat' >';foreach($matnames as $item) {?><option value='<?=$item['name']?>'><?=htmlspecialchars($item['name'])?></option><?}?></select>
<input type='submit' value='Выбрать материал' name='ismaterial' />
<input type='submit' value='Удалить материал' name='delmaterial' /><?}?></form><form action='' method='post'><? if(isset($textik)){echo'<b>Название материала</b><input type='text' value='$mn' name='mn' id='mn' />
<textarea name='content' id='editor' >';
print $textik; echo'</textarea> <script type='text/javascript'>
CKEDITOR.replace( 'editor' ); // CKEDITOR подключить к текстовому полю с идентификатором editor
</script>
<input type='submit' value='Сохранить изменения' name='savem' />'; }?> </form></div></div>
..aplicationviewsadmintitle.php
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
<title>Skutor - Kohana Framework</title>
<link href='/css/stylesheetadmin.css' rel='stylesheet' type='text/css' />
<script type='text/javascript' src='/js/jquery-1.7.1.js' ></script>
<script type='text/javascript' src='/ckeditor/ckeditor.js'></script>
</head><body><div id='top_bar_black'> <div id='logo_container'>
<div id='logo_image'> </div> <div id='nav_block'>
<div class='nav_button'><a href='/'>На главную </a></div>
<div class='nav_button'><a href='/admin'> Добавление</a></div>
<div class='nav_button'><a href='/admin/edit'> Редактирование</a></div>
<div class='nav_button'><a href='/admin/users'> Пользователи</a></div> </div></div></div>
<div id='content_container'><?php echo $content ?>
</div><div id='clear'></div><div id='bottom_bar_black'> <div id='main_container'></div> </div><div id='copywriteblock'> <a href='mailto:skutorlike@mail.ru'>© Автор сайта: skutor </a></div></body></html>
..aplicationviewsadminusersview.php
<p><h3>Страница управления пользователями</p></h3><div id='analitics'><p>
<font color='green'> Зарегистрировано пользователей: </font> <?=$usercount?>
<br /><font color='red'> Администраторов: </font> <?=$admincount?></p></div>
<div id='search'><form method='post' action=''>
<h3 style='font-size: 16px; font-family: Verdana;'>Поиск пользователя: </h3>
<input type='text' name='username' /><input type='submit' value='Найти' name='SearchGo' /></form>
<?php if(isset($findok)){echo '<p style='color: green;'>Результат: </p>';
foreach($name as $item) {echo $item['username'].'<br />';}}else
echo 'Ничего не найдено';?></div><div id='clear'></div>
..aplicationmessagesaddmatErrors.php
<? // тест документ, не используется!
return array (
'materialname'=> array(
'not_empty'=> 'Вы не дали название материалу',
'min_length'=> 'Название материала слишком короткое',
'max_length'=>'Название не должно быть длиннее 20 символов',
'alpha_numeric'=>'Название может использовать только английские и целочисленные символы верхнего и нижнего регистров. Без специальных сиволов.',
), 'tags'=> array('not_empty'=> 'Вы не ввели ни одного тега.', ),);
..aplicationmessagescatErrors.php
<? return array (
'name'=> array(
'not_empty'=> 'Название категории не должно быть пустым.',
'min_length'=> 'Вы ввели название категории менее трех символов.',
'regex'=>'Можно использовать только русские,английские и целочисленные символы верхнего и нижнего регистров. Без специальных сиволов.', ),
'parentID'=> array(
'check_id'=>'Нельзя создать категорию, так как не существует родительской категории.',),
'nametrans'=> array(
'unique_url'=>'URL уже существует.',),
'password'=> array(
'not_empty'=> 'Пароль не должен быть пустым.',
'min_length'=> 'Пароль должен содержать не менее 7 символов.',
'max_length'=>'Пароль должен содержать не более 16 символов.',
'regex'=>'Можно использовать только английские и целочисленные символы верхнего и нижнего регистров. Без специальных сиволов.', ),
'oldpass' => array(
'not_empty' => 'Вы не ввели старый пароль',
'checkOldPass' => 'Ошибка в старом пароле', ),
'newpass1' => array(
'not_empty' => 'Вы не ввели новый пароль',
'matches' => 'Новые пароли должны совпадать',
'min_length'=> 'Пароль должен содержать не менее 7 символов.',
'max_length'=>'Пароль должен содержать не более 16 символов.',
'regex'=>'Можно использовать только английские и целочисленные символы верхнего и нижнего регистров. Без специальных сиволов.', ),);
..aplicationmessagespassErrors.php
<? // тест документ, не используется!
return array ('password'=> array(
'not_empty'=> 'Пароль не должен быть пустым.',
'min_length'=> 'Пароль должен содержать не менее 7 символов.',
'max_length'=>'Пароль должен содержать не более 16 символов.',
'regex'=>'Можно использовать только английские и целочисленные символы верхнего и нижнего регистров. Без специальных сиволов.', ), );
..aplicationmessagesvalidationmyuser.php
<? return array ('username'=> array(
'not_empty'=> 'Вы не заполнили поле Email.',
'email'=> 'Это не Email.',
'username_unique'=> 'Данный Email уже зарегистрирован.', ),);
..aplicationmessagesvalidationregcode.php
<? return array ( 'code'=> array(
'not_empty'=> 'Поле регистрационного кода не должно быть пустым.',
'bad_code'=> 'Код используется другим пользователем или не существует.', ),);
..aplicationmessagesemailthemesregister.php
<?php defined('SYSPATH') or die('No direct script access.'); return array(
'subject' => 'Подтверждение регистрации',);
..aplicationmessagesemailthemesrememberpassword.php
<?php defined('SYSPATH') or die('No direct script access.'); return array(
'subject' => 'Восстановление пароля', );
..aplicationmessagesemailthemesrememberpasswordcomplete.php
<?php defined('SYSPATH') or die('No direct script access.'); return array(
'subject' => 'Ваш новый пароль', );
SQL dump базы данных “kgksite”
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `materials`
-- ----------------------------
DROP TABLE IF EXISTS `materials`;
CREATE TABLE `materials` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(10) unsigned NOT NULL,
`content` text NOT NULL,
`createtime` int(10) DEFAULT NULL,
`modtime` int(10) DEFAULT NULL,
`name` varchar(25) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of materials
-- ----------------------------
INSERT INTO `materials` VALUES ('1', '5', '<p>rnВы можете свзяаться со мной по адресу:</p>rn<p>rn<a href='mailto:skutorlike@mail.ru?subject=%D0%A1%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B5%20%D1%81%20%D0%B2%D0%B0%D1%88%D0%B5%D0%B3%D0%BE%20%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0%20Kohana'>skutorlike@mail.ru</a></p>rn', '1329132907', null, 'Email');
INSERT INTO `materials` VALUES ('7', '4', '<p>rnКакая-то информация</p>rn', '1336382841', null, 'Материал1');
INSERT INTO `materials` VALUES ('8', '4', '<p>n<strong>Некая информация к Материалу № 2.</strong></p>n', '1337088918', '1338127500', 'sdfsdfsdf');
INSERT INTO `materials` VALUES ('9', '4', '<p>ninformation, many many information =)</p>n', '1337088918', '1338127561', 'playgamer');
INSERT INTO `materials` VALUES ('11', '5', '<p>rntext for example</p>rn', '1338381423', null, 'example2');
-- ----------------------------
-- Table structure for `regcodes`
-- ----------------------------
DROP TABLE IF EXISTS `regcodes`;
CREATE TABLE `regcodes` (
`id` int(7) NOT NULL AUTO_INCREMENT,
`code` varchar(32) NOT NULL,
`user_id` int(7) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of regcodes
-- ----------------------------
INSERT INTO `regcodes` VALUES ('1', '111', '1');
INSERT INTO `regcodes` VALUES ('2', '222', '2');
INSERT INTO `regcodes` VALUES ('3', '333', '2');
INSERT INTO `regcodes` VALUES ('4', '787', '9');
INSERT INTO `regcodes` VALUES ('5', '121', '3');
-- ----------------------------
-- Table structure for `roles`
-- ----------------------------
DROP TABLE IF EXISTS `roles`;
CREATE TABLE `roles` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`description` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of roles
-- ----------------------------
INSERT INTO `roles` VALUES ('1', 'login', 'Login privileges, granted after account confirmation');
INSERT INTO `roles` VALUES ('2', 'admin', 'Administrative user, has access to everything.');
-- ----------------------------
-- Table structure for `roles_users`
-- ----------------------------
DROP TABLE IF EXISTS `roles_users`;
CREATE TABLE `roles_users` (
`user_id` int(11) unsigned NOT NULL,
`role_id` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of roles_users
-- ----------------------------
INSERT INTO `roles_users` VALUES ('1', '1');
INSERT INTO `roles_users` VALUES ('1', '2');
INSERT INTO `roles_users` VALUES ('2', '1');
INSERT INTO `roles_users` VALUES ('3', '1');
-- ----------------------------
-- Table structure for `tags`
-- ----------------------------
DROP TABLE IF EXISTS `tags`;
CREATE TABLE `tags` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`url` varchar(100) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tags
-- ----------------------------
INSERT INTO `tags` VALUES ('1', 'email', 'http://localhost/materials/showcontent/59');
INSERT INTO `tags` VALUES ('2', 'author', 'http://localhost/materials/showcontent/60');
INSERT INTO `tags` VALUES ('3', 'contact', 'http://localhost/materials/showcontent/61');
INSERT INTO `tags` VALUES ('7', 'deletematerials', 'http://localhost/materials/showcontent/7');
INSERT INTO `tags` VALUES ('8', 'info', 'http://localhost/materials/showcontent/8');
INSERT INTO `tags` VALUES ('9', 'material2', 'http://localhost/materials/showcontent/9');
INSERT INTO `tags` VALUES ('10', 'mat2', 'http://localhost/materials/showcontent/10');
INSERT INTO `tags` VALUES ('11', 'zero', 'http://localhost/materials/showcontent/11');
INSERT INTO `tags` VALUES ('12', 'example', 'http://localhost/materials/showcontent/12');
INSERT INTO `tags` VALUES ('13', 'foryou', 'http://localhost/materials/showcontent/13');
INSERT INTO `tags` VALUES ('14', 'test', 'http://localhost/materials/showcontent/14');
INSERT INTO `tags` VALUES ('15', 'second', 'http://localhost/materials/showcontent/15');
-- ----------------------------
-- Table structure for `tags_materials`
-- ----------------------------
DROP TABLE IF EXISTS `tags_materials`;
CREATE TABLE `tags_materials` (
`tag_id` int(10) NOT NULL,
`material_id` int(10) NOT NULL,
KEY `FK_tags_materials_tags` (`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tags_materials
-- ----------------------------
INSERT INTO `tags_materials` VALUES ('1', '1');
INSERT INTO `tags_materials` VALUES ('2', '1');
INSERT INTO `tags_materials` VALUES ('3', '1');
INSERT INTO `tags_materials` VALUES ('1', '2');
INSERT INTO `tags_materials` VALUES ('7', '3');
INSERT INTO `tags_materials` VALUES ('8', '7');
INSERT INTO `tags_materials` VALUES ('9', '8');
INSERT INTO `tags_materials` VALUES ('10', '8');
INSERT INTO `tags_materials` VALUES ('11', '9');
INSERT INTO `tags_materials` VALUES ('12', '10');
INSERT INTO `tags_materials` VALUES ('13', '10');
INSERT INTO `tags_materials` VALUES ('14', '11');
INSERT INTO `tags_materials` VALUES ('15', '12');
-- ----------------------------
-- Table structure for `tree`
-- ----------------------------
DROP TABLE IF EXISTS `tree`;
CREATE TABLE `tree` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
`nametrans` varchar(250) NOT NULL,
`left_key` int(10) NOT NULL,
`right_key` int(10) NOT NULL,
`level` int(10) NOT NULL,
PRIMARY KEY (`id`,`nametrans`),
UNIQUE KEY `url` (`nametrans`) USING BTREE,
KEY `key` (`left_key`,`right_key`,`level`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tree
-- ----------------------------
INSERT INTO `tree` VALUES ('1', 'Главная', 'main', '1', '34', '0');
INSERT INTO `tree` VALUES ('3', 'Дизайн', 'Dizayn', '18', '19', '1');
INSERT INTO `tree` VALUES ('4', 'Движок', 'Dvijok', '20', '23', '1');
INSERT INTO `tree` VALUES ('5', 'Контакты', 'Kontaktyi', '24', '25', '1');
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(40) NOT NULL,
`username` varchar(40) NOT NULL,
`password` varchar(64) NOT NULL,
`logins` int(10) unsigned NOT NULL DEFAULT '0',
`last_login` int(10) unsigned DEFAULT NULL,
`rempass` varchar(70) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_username` (`username`),
UNIQUE KEY `uniq_email` (`email`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'skutorlike@mail.ru', 'skutorlike@mail.ru', '56878f874f984e7030652aa0d61550b9d28bec2fe256161c0e56bfd61de7794b', '112', '1338720949', null);
INSERT INTO `users` VALUES ('2', 'zoikazaripova@mail.ru', 'zoikazaripova@mail.ru', '56878f874f984e7030652aa0d61550b9d28bec2fe256161c0e56bfd61de7794b', '0', null, null);
INSERT INTO `users` VALUES ('3', 'winist@yandex.ru', 'winist@yandex.ru', '56878f874f984e7030652aa0d61550b9d28bec2fe256161c0e56bfd61de7794b', '2', '1338151839', null);
-- ----------------------------
-- Table structure for `user_tokens`
-- ----------------------------
DROP TABLE IF EXISTS `user_tokens`;
CREATE TABLE `user_tokens` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`user_agent` varchar(40) NOT NULL,
`token` varchar(40) NOT NULL,
`type` varchar(100) NOT NULL,
`created` int(10) unsigned NOT NULL,
`expires` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_token` (`token`),
KEY `fk_user_id` (`user_id`),
CONSTRAINT `user_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user_tokens
-- ----------------------------
Конфигурационные файлы
Конфигурационные файлы модулей и машрутов Kohana, Apache, PHP, MySQL не включены. Их можно на информационном носителе прилагаемом к диклому.