├── .htaccess
├── README.md
├── application
├── bootstrap.php
├── controllers
│ ├── controller_404.php
│ ├── controller_admin.php
│ ├── controller_contacts.php
│ ├── controller_login.php
│ ├── controller_main.php
│ ├── controller_portfolio.php
│ └── controller_services.php
├── core
│ ├── controller.php
│ ├── model.php
│ ├── route.php
│ └── view.php
├── models
│ └── model_portfolio.php
└── views
│ ├── 404_view.php
│ ├── admin_view.php
│ ├── contacts_view.php
│ ├── login_view.php
│ ├── main_view.php
│ ├── portfolio_view.php
│ ├── services_view.php
│ └── template_view.php
├── css
└── style.css
├── images
├── 00bd.png
├── 404.png
├── cap.jpg
├── office-full.jpg
└── office-small.jpg
├── index.php
└── js
└── jquery-1.6.2.js
/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine On
2 | RewriteCond %{REQUEST_FILENAME} !-f
3 | RewriteCond %{REQUEST_FILENAME} !-d
4 | RewriteRule .* index.php [L]
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | Исходные коды проекта, описанного в статье: "Реализация MVC паттерна на примере создания сайта-визитки на PHP ".
3 |
4 | © vitalyswipe
5 |
6 |
--------------------------------------------------------------------------------
/application/bootstrap.php:
--------------------------------------------------------------------------------
1 | аутентификацию
11 | > кеширование
12 | > работу с формами
13 | > абстракции для доступа к данным
14 | > ORM
15 | > Unit тестирование
16 | > Benchmarking
17 | > Работу с изображениями
18 | > Backup
19 | > и др.
20 | */
21 |
22 | require_once 'core/route.php';
23 | Route::start(); // запускаем маршрутизатор
24 |
--------------------------------------------------------------------------------
/application/controllers/controller_404.php:
--------------------------------------------------------------------------------
1 | view->generate('404_view.php', 'template_view.php');
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/application/controllers/controller_admin.php:
--------------------------------------------------------------------------------
1 | view->generate('admin_view.php', 'template_view.php');
18 | }
19 | else
20 | {
21 | session_destroy();
22 | Route::ErrorPage404();
23 | }
24 |
25 | }
26 |
27 | // Действие для разлогинивания администратора
28 | function action_logout()
29 | {
30 | session_start();
31 | session_destroy();
32 | header('Location:/');
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/application/controllers/controller_contacts.php:
--------------------------------------------------------------------------------
1 | view->generate('contacts_view.php', 'template_view.php');
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/application/controllers/controller_login.php:
--------------------------------------------------------------------------------
1 | view->generate('login_view.php', 'template_view.php', $data);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/application/controllers/controller_main.php:
--------------------------------------------------------------------------------
1 | view->generate('main_view.php', 'template_view.php');
9 | }
10 | }
--------------------------------------------------------------------------------
/application/controllers/controller_portfolio.php:
--------------------------------------------------------------------------------
1 | model = new Model_Portfolio();
9 | $this->view = new View();
10 | }
11 |
12 | function action_index()
13 | {
14 | $data = $this->model->get_data();
15 | $this->view->generate('portfolio_view.php', 'template_view.php', $data);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/application/controllers/controller_services.php:
--------------------------------------------------------------------------------
1 | view->generate('services_view.php', 'template_view.php');
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/application/core/controller.php:
--------------------------------------------------------------------------------
1 | view = new View();
11 | }
12 |
13 | // действие (action), вызываемое по умолчанию
14 | function action_index()
15 | {
16 | // todo
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/application/core/model.php:
--------------------------------------------------------------------------------
1 | методы нативных библиотек pgsql или mysql;
9 | > методы библиотек, реализующих абстракицю данных. Например, методы библиотеки PEAR MDB2;
10 | > методы ORM;
11 | > методы для работы с NoSQL;
12 | > и др.
13 | */
14 |
15 | // метод выборки данных
16 | public function get_data()
17 | {
18 | // todo
19 | }
20 | }
--------------------------------------------------------------------------------
/application/core/route.php:
--------------------------------------------------------------------------------
1 | цепляет классы контроллеров и моделей;
6 | > создает экземпляры контролеров страниц и вызывает действия этих контроллеров.
7 | */
8 | class Route
9 | {
10 |
11 | static function start()
12 | {
13 | // контроллер и действие по умолчанию
14 | $controller_name = 'Main';
15 | $action_name = 'index';
16 |
17 | $routes = explode('/', $_SERVER['REQUEST_URI']);
18 |
19 | // получаем имя контроллера
20 | if ( !empty($routes[1]) )
21 | {
22 | $controller_name = $routes[1];
23 | }
24 |
25 | // получаем имя экшена
26 | if ( !empty($routes[2]) )
27 | {
28 | $action_name = $routes[2];
29 | }
30 |
31 | // добавляем префиксы
32 | $model_name = 'Model_'.$controller_name;
33 | $controller_name = 'Controller_'.$controller_name;
34 | $action_name = 'action_'.$action_name;
35 |
36 | /*
37 | echo "Model: $model_name ";
38 | echo "Controller: $controller_name ";
39 | echo "Action: $action_name ";
40 | */
41 |
42 | // подцепляем файл с классом модели (файла модели может и не быть)
43 |
44 | $model_file = strtolower($model_name).'.php';
45 | $model_path = "application/models/".$model_file;
46 | if(file_exists($model_path))
47 | {
48 | include "application/models/".$model_file;
49 | }
50 |
51 | // подцепляем файл с классом контроллера
52 | $controller_file = strtolower($controller_name).'.php';
53 | $controller_path = "application/controllers/".$controller_file;
54 | if(file_exists($controller_path))
55 | {
56 | include "application/controllers/".$controller_file;
57 | }
58 | else
59 | {
60 | /*
61 | правильно было бы кинуть здесь исключение,
62 | но для упрощения сразу сделаем редирект на страницу 404
63 | */
64 | Route::ErrorPage404();
65 | }
66 |
67 | // создаем контроллер
68 | $controller = new $controller_name;
69 | $action = $action_name;
70 |
71 | if(method_exists($controller, $action))
72 | {
73 | // вызываем действие контроллера
74 | $controller->$action();
75 | }
76 | else
77 | {
78 | // здесь также разумнее было бы кинуть исключение
79 | Route::ErrorPage404();
80 | }
81 |
82 | }
83 |
84 | function ErrorPage404()
85 | {
86 | $host = 'http://'.$_SERVER['HTTP_HOST'].'/';
87 | header('HTTP/1.1 404 Not Found');
88 | header("Status: 404 Not Found");
89 | header('Location:'.$host.'404');
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/application/core/view.php:
--------------------------------------------------------------------------------
1 | '2012',
15 | 'Site' => 'http://DunkelBeer.ru',
16 | 'Description' => 'Промо-сайт темного пива Dunkel от немецкого производителя Löwenbraü выпускаемого в России пивоваренной компанией "CАН ИнБев".'
17 | ),
18 |
19 | array(
20 | 'Year' => '2012',
21 | 'Site' => 'http://ZopoMobile.ru',
22 | 'Description' => 'Русскоязычный каталог китайских телефонов компании Zopo на базе Android OS и аксессуаров к ним.'
23 | ),
24 |
25 | array(
26 | 'Year' => '2012',
27 | 'Site' => 'http://GeekWear.ru',
28 | 'Description' => 'Интернет-магазин брендовой одежды для гиков.'
29 | ),
30 |
31 | array(
32 | 'Year' => '2011',
33 | 'Site' => 'http://РоналВарвар.рф',
34 | 'Description' => 'Промо-сайт мультфильма "Ронал-варвар" от норвежских режиссеров. Мультфильм о самом нетипичном варваре на Земле, переполненный интересными приключениями и забавными ситуациями.'
35 | ),
36 |
37 | array(
38 | 'Year' => '2011',
39 | 'Site' => 'http://TompsonTatoo.ru',
40 | 'Description' => 'Персональный сайт-блог художника-татуировщика Алексея Томпсона из Санкт-Петербурга.'
41 | ),
42 |
43 | array(
44 | 'Year' => '2011',
45 | 'Site' => 'http://DaftState.ru',
46 | 'Description' => 'Страничка музыкальных и сануд продюсеров из команды "DaftState", работающих в стилях BreakBeat и BigBeat.'
47 | ),
48 |
49 | array(
50 | 'Year' => '2011',
51 | 'Site' => 'http://TiltPeople.ru',
52 | 'Description' => 'Сайт сообщества фотографов в стиле Tilt Shif.'
53 | ),
54 |
55 | array(
56 | 'Year' => '2011',
57 | 'Site' => 'http://AbsurdGames.ru',
58 | 'Description' => 'Страничка российской команды разработчиков независимых игр с необычной физикой и сюрреалистической графикой.'
59 | ),
60 |
61 | );
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/application/views/404_view.php:
--------------------------------------------------------------------------------
1 | 404
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/application/views/admin_view.php:
--------------------------------------------------------------------------------
1 | Панель администрирования
2 |
3 | Админка...
4 |
11 |
12 |
--------------------------------------------------------------------------------
/application/views/contacts_view.php:
--------------------------------------------------------------------------------
1 | Контакты
2 |
3 | icq: 199199538
4 | skypeid: vitalyswipe
5 | email: vitalyswipe@gmail.com
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/application/views/login_view.php:
--------------------------------------------------------------------------------
1 | Страница авторизации
2 |
3 |
21 |
22 |
23 |
24 |
25 | Авторизация прошла успешно.
26 |
27 | Логин и/или пароль введены неверно.
28 |
29 |
--------------------------------------------------------------------------------
/application/views/main_view.php:
--------------------------------------------------------------------------------
1 | Добро пожаловать!
2 |
3 |
4 | ОЛОЛОША TEAM - команда первоклассных специалистов в области разработки веб-сайтов с многолетним опытом коллекционирования мексиканских масок, бронзовых и каменных статуй из Индии и Цейлона, барельефов и изваяний, созданных мастерами Экваториальной Африки пять-шесть веков назад. Сотрудники компании надевают костюм и галстук при посещении некоторых фешенебельных ресторанов, сосредоточенных в районе Центральной площади и железнодорожного вокзала. Полынно-кустарниковая растительность здесь параллельна. Пересечения улиц сплетаются в урбанистический кедровый пейзаж, при этом разрешен провоз 3 бутылок крепких спиртных напитков, 2 бутылок вина; 1 литр духов в откупоренных флаконах, 2 литра одеколона в откупоренных флаконах. Когда из офиса с шумом выбегают мужчины в костюмах демонов и смешиваются с толпой, царящая в нашей студии атмосфера напоминает очаг многовекового орошаемого земледелия, и не надо забывать, что время здесь отстает от московского на 2 часа. Из первых блюд распространены супы-пюре и бульоны, но подают их редко,
5 | Для гостей также открываются погреба Прибалатонских винодельческих хозяйств, известных отличными сортами вин "Олазрислинг" и "Сюркебарат".
6 | В ресторане стоимость обслуживания (15%) включена в счет; в баре и кафе - 10-15% счета только за услуги официанта; в такси - чаевые включены в стоимость проезда, тем не менее портер неравномерен.
7 | В пределах личных потребностей сотрудники компании точно отражают широкий кристаллический фундамент. Помимо трендовых сертификатов, также имеются справки о прививках против бешенства и результаты анализа на бешенство через 120 дней и за 30 дней до начала работы над вашим проектом. Большинство сотрудников компании (около 5%) очень дружелюбны, приветливы и гостеприимны. При этом королевские полномочия находятся в руках бамбукового медведя панды. Это и есть всемирно известный центр огранки алмазов и торговли бриллиантами - ОЛОЛОША TEAM .
8 |
--------------------------------------------------------------------------------
/application/views/portfolio_view.php:
--------------------------------------------------------------------------------
1 | Портфолио
2 |
3 |
4 | Все проекты в следующей таблице являются вымышленными, поэтому даже не пытайтесь перейти по приведенным ссылкам.
5 | Год Проект Описание
6 | '.$row['Year'].' '.$row['Site'].' '.$row['Description'].' ';
11 | }
12 |
13 | ?>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/application/views/services_view.php:
--------------------------------------------------------------------------------
1 | Услуги
2 |
3 | Компания ОЛОЛОША TEAM оказывает следующие услуги:
4 |
5 | Разработка программного обеспечения на заказ
6 | Мы разрабатываем программное обеспечение, в том числе проводим работы по проектированию, разработке, тестированию и внедрению программных продуктов.
7 |
8 | Сопровождение программных продуктов и техническая поддержка
9 | Наша комманда осуществляет техническую поддержку и развитие программных продуктов, как собственного производства, так и сторонних организаций.
10 |
11 | Независимое тестирование программного обеспечения Сотрудники нашей компании профессионально выполнят тестирование новых версий программных продуктов, включая функциональное, нагрузочное и модульное тестирование. Независимое тестирование позволит определить работоспособность программного продукта и выявить критические точки при большой нагрузке.
12 |
13 | Документирование
14 | Мы также выполним работы, связанные с разработкой и поддержкой документации на программное обеспечение, включая технический проект, руководства пользователя и т.п.
15 |
16 | Аутсорсинг разработки и поддержки программного обеспечения
17 | Наша компания возьмет на себя выполнение процессов по разработке и сопровождению программного обеспечения. Это позволит вам сосредоточить внимание на развитии бизнеса и укреплении отношений с клиентами.
18 |
19 |
--------------------------------------------------------------------------------
/application/views/template_view.php:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 | ОЛОЛОША TEAM
20 |
21 |
22 |
23 |
24 |
41 |
42 |
43 |
44 |
58 |
59 |
91 |
92 |
93 |
94 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
115 |
116 |
О Компании
117 |
118 | Вот дом.
119 | Который построил Джек.
120 |
121 | А это пшеница.
122 | Которая в тёмном чулане хранится
123 | В доме,
124 | Который построил Джек.
125 |
126 | А это весёлая птица-синица,
127 | Которая ловко ворует пшеницу,
128 | Которая в тёмном чулане хранится
129 | В доме,
130 | Который построил Джек.
131 |
132 | Вот кот,
133 | Который пугает и ловит синицу,
134 | Которая ловко ворует пшеницу,
135 | Которая в тёмном чулане хранится
136 | В доме,
137 | Который построил Джек.
138 |
139 |
140 |
141 |
142 |
143 |
146 |
147 |
--------------------------------------------------------------------------------
/css/style.css:
--------------------------------------------------------------------------------
1 | /*
2 | Design by Free CSS Templates
3 | http://www.freecsstemplates.org
4 | Released for free under a Creative Commons Attribution 3.0 License
5 |
6 | Name : Accumen
7 | Description: A two-column, fixed-width design with dark color scheme.
8 | Version : 1.0
9 | Released : 20120712
10 | */
11 |
12 | * {
13 | margin: 0;
14 | padding: 0;
15 | }
16 |
17 | a {
18 | text-decoration: underline;
19 | color: #353535;
20 | }
21 |
22 | a:hover {
23 | text-decoration: none;
24 | }
25 |
26 | body {
27 | line-height: 1.75em;
28 | background: #fff url('../images/00bd.png');
29 |
30 | font-size: 11.5pt;
31 | color: #353535;
32 | }
33 |
34 | body,input {
35 | font-family: Kreon, serif;
36 | }
37 |
38 | br.clearfix {
39 | clear: both;
40 | }
41 |
42 | h1,h2,h3,h4 {
43 | text-transform: uppercase;
44 | font-weight: normal;
45 | font-family: "Open Sans", sans-serif;
46 | color: #353535;
47 | margin-bottom: 1em;
48 | }
49 |
50 | h1 {
51 | font-size: 1.75em;
52 | }
53 |
54 | h2 {
55 | font-size: 1.5em;
56 | }
57 |
58 | h3 {
59 | font-size: 1.25em;
60 | }
61 |
62 | h4 {
63 | font-size: 1em;
64 | }
65 |
66 | img.alignleft {
67 | float: left;
68 | margin: 5px 30px 20px 0;
69 | }
70 |
71 | img.aligntop {
72 | margin: 5px 0 20px 0;
73 | }
74 |
75 | p {
76 | margin-bottom: 1.5em;
77 | }
78 |
79 | ul {
80 | margin-bottom: 1.5em;
81 | }
82 |
83 | ul h4 {
84 | margin-bottom: 0.35em;
85 | }
86 |
87 | a {
88 | color: #353535;
89 | }
90 |
91 | #content {
92 | padding: 0 0 0 10px;
93 | width: 615px;
94 | margin: 0 0 0 285px;
95 | }
96 |
97 | #footer {
98 | padding: 20px 0 20px 0;
99 | text-align: center;
100 | text-shadow: 1px 1px 0px rgba(255,255,255,0.7);
101 | color: #353535;
102 | }
103 |
104 | #footer a {
105 | color: #353535;
106 | }
107 |
108 | #header {
109 | height: 130px;
110 | padding: 40px;
111 | position: relative;
112 | background: url(../images/cap.jpg) no-repeat 85px 30px;
113 | }
114 |
115 | #logo {
116 | position: absolute;
117 | top: 40px;
118 | left: 20px;
119 | height: 130px;
120 | line-height: 130px;
121 |
122 | }
123 |
124 | #logo a {
125 | color: #ffffff;
126 | text-shadow: black 0px 0px 7px;
127 | text-decoration: none;
128 | font-family: "Open Sans", sans-serif;
129 | font-size: 35px;
130 | }
131 |
132 |
133 | #logo img {
134 | margin-left: 70px;
135 | vertical-align: middle;
136 | }
137 |
138 | #menu {
139 | line-height: 57px;
140 | position: absolute;
141 | right: 40px;
142 | top: 76px;
143 | height: 57px;
144 | font-family: "Open Sans", sans-serif;
145 | }
146 |
147 | #menu a {
148 | text-transform: uppercase;
149 | text-decoration: underline;
150 | color: #1C1C1C;
151 | font-size: 1.2em;
152 | }
153 |
154 | #menu a:hover {
155 | text-decoration: none;
156 | }
157 |
158 | #menu ul {
159 | padding: 0 20px 0 20px;
160 | list-style: none;
161 | }
162 |
163 | #menu ul li {
164 | display: inline;
165 | padding: 10px 10px 10px 10px;
166 | margin: 0 8px 0 8px;
167 | }
168 |
169 | #page {
170 | margin: 0;
171 | position: relative;
172 | width: 900px;
173 | padding: 20px 40px 0 40px;
174 | }
175 |
176 | #page .section-list {
177 | padding-left: 0;
178 | list-style: none;
179 | }
180 |
181 | #page .section-list li {
182 | padding: 25px 0 25px 0;
183 | clear: both;
184 | }
185 |
186 | #sidebar ul {
187 | list-style: none;
188 | }
189 |
190 | #sidebar ul li {
191 | border-top: solid 1px #e3e3e3;
192 | padding: 10px 0 10px 0;
193 | }
194 |
195 | #sidebar ul li.first {
196 | padding-top: 0;
197 | border-top: 0;
198 | }
199 |
200 | #page-bottom {
201 | padding: 40px 40px 0 40px;
202 | color: #353535;
203 | background: #f3f3f3;
204 | position: relative;
205 | width: 898px;
206 | border-top: solid 1px #e3e3e3;
207 | box-shadow: inset 0px 0px 0px 1px #fff;
208 | text-shadow: 1px 1px 0px rgba(255,255,255,0.9);
209 | }
210 |
211 | #page-bottom a {
212 | color: #1B1A18;
213 | }
214 |
215 | #page-bottom h2, #page-bottom h3, #page-bottom h4 {
216 | color: #353535;
217 | }
218 |
219 | #page-bottom ul {
220 | list-style: none;
221 | }
222 |
223 | #page-bottom ul li {
224 | border-top: solid 1px #e3e3e3;
225 | padding: 10px 0 10px 0;
226 | }
227 |
228 | #page-bottom ul li.first {
229 | border-top: 0;
230 | padding-top: 0;
231 | }
232 |
233 | #page-bottom-content {
234 | width: 615px;
235 | margin: 0 0 0 290px;
236 | }
237 |
238 | #page-bottom-sidebar {
239 | float: left;
240 | width: 250px;
241 | }
242 |
243 | #sidebar {
244 | position: relative;
245 | left: -20px;
246 | top: -20px;
247 | float: left;
248 | width: 240px;
249 | background: #f3f3f3;
250 | padding: 20px;
251 | border: solid 1px #e3e3e3;
252 | margin: 0 10px 0 0;
253 | text-shadow: 1px 1px 0px rgba(255,255,255,1);
254 | box-shadow: inset 0px 0px 0px 1px #fff;
255 | }
256 |
257 | #wrapper {
258 | width: 978px;
259 | position: relative;
260 | background: #FFF;
261 | margin: 0 auto 0 auto;
262 | box-shadow: 10px 100px 150px 0px rgba(0,0,0,0.15);
263 | border: solid 1px #f3f3f3;
264 | border-top: 0;
265 | }
266 |
267 | .box img {
268 | margin: 0px 20px 0px 0px;
269 | border: solid 1px #e3e3e3;
270 | }
271 |
272 | .box p {
273 | margin-bottom: 0em;
274 | }
275 |
276 | .box ul{
277 | margin-bottom: 0em;
278 | list-style: square inside;
279 | }
280 |
281 | .box table {
282 | border-collapse:collapse;
283 | }
284 |
285 | .box table, th, td {
286 | border: 1px solid #e3e3e3;
287 | padding: 5px;
288 | }
289 |
--------------------------------------------------------------------------------
/images/00bd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitalyswipe/tinymvc/0b3b977daf18b91d917d437611db5d0c8fce57d6/images/00bd.png
--------------------------------------------------------------------------------
/images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitalyswipe/tinymvc/0b3b977daf18b91d917d437611db5d0c8fce57d6/images/404.png
--------------------------------------------------------------------------------
/images/cap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitalyswipe/tinymvc/0b3b977daf18b91d917d437611db5d0c8fce57d6/images/cap.jpg
--------------------------------------------------------------------------------
/images/office-full.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitalyswipe/tinymvc/0b3b977daf18b91d917d437611db5d0c8fce57d6/images/office-full.jpg
--------------------------------------------------------------------------------
/images/office-small.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitalyswipe/tinymvc/0b3b977daf18b91d917d437611db5d0c8fce57d6/images/office-small.jpg
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 |