diff --git a/.gitignore b/.gitignore
index 1fc1b3b..ac29e4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.idea
.DS_Store
public/.DS_Store
+vendor/
diff --git a/.htaccess b/.htaccess
old mode 100755
new mode 100644
index a4cbb93..b88bba0
--- a/.htaccess
+++ b/.htaccess
@@ -1,5 +1,5 @@
RewriteEngine on
RewriteRule ^$ public/ [L]
- RewriteRule (.*) public/$1 [L]
-
\ No newline at end of file
+ RewriteRule ((?s).*) public/$1 [L]
+
diff --git a/.htrouter.php b/.htrouter.php
new file mode 100644
index 0000000..b5ee59e
--- /dev/null
+++ b/.htrouter.php
@@ -0,0 +1,15 @@
+
+Phalcon Team
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..220fd99
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020-present The Phalcon PHP Framework
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 1f9666b..2055a23 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ performance and lower resource consumption.
This is a very simple tutorial to understand the basis of work with Phalcon.
-Check out a [explanation article][1].
+Check out an [explanation article][1].
## Get Started
@@ -13,17 +13,56 @@ Check out a [explanation article][1].
To run this application on your machine, you need at least:
-* PHP >= 5.4
-* [Apache][2] Web Server with [mod_rewrite][3] enabled or [Nginx][4] Web Server
+* PHP >= 8.0+
+* Server Any of the following
+ * [Apache][2] Web Server with [mod_rewrite][3] enabled
+ * [Nginx][4] Web Server
* Latest stable [Phalcon Framework release][5] extension enabled
+## Running the application locally
+
+* Clone the repository to a folder on your machine
+* Navigate to that folder
+* Run `docker compose up -d`
+* After the build process is completed, you will have the following:
+ * PHP 8.0 (`tutorial-8.0`)
+ * PHP 8.1 (`tutorial-8.1`)
+ * PHP 8.2 (`tutorial-8.2`)
+ * PHP 8.3 (`tutorial-8.3`)
+* You can check the application on your local browser by finding the IP address of the chosen environment and launching it. For example, if you wish to check the PHP 8.3 environment, type the following in your terminal:
+
+```shell
+docker inspect tutorial-8.3
+```
+This will output a JSON file, where you can find the IP address of the container on your local machine.
+
+```shell
+...
+ "EndpointID": "563ba90563ffb7ad5c30689f1216ec4c2e1625d170eb0279e78c001973464691",
+ "Gateway": "172.29.0.1",
+ "IPAddress": "172.29.0.5",
+ "IPPrefixLen": 16,
+...
+```
+
+Launch a browser and visit the site using that IP address (`http://172.29.0.5`)
+
+To enter an environment and run different commands, such as populating the database:
+
+```shell
+docker exec -it tutorial-8.3 /bin/bash
+```
+
## License
-Phalcon Tutorial is open-sourced software licensed under the [New BSD License][6]. © Phalcon Framework Team and contributors
+Phalcon Tutorial is open-sourced software licensed under the [MIT][6]. © Phalcon Framework Team and
+contributors
-[1]: http://docs.phalconphp.com/en/latest/reference/tutorial.html
+[1]: https://docs.phalcon.io/latest/tutorial-basic
[2]: http://httpd.apache.org/
[3]: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
[4]: http://nginx.org/
[5]: https://github.com/phalcon/cphalcon/releases
-[6]: https://github.com/phalcon/tutorial/blob/master/docs/LICENSE.md
+[6]: https://github.com/phalcon/tutorial/blob/master/docs/LICENSE
+[7]: https://github.com/phalcon/phalcon-devtools
+[8]: https://docker.com
diff --git a/app/controllers/IndexController.php b/app/controllers/IndexController.php
deleted file mode 100644
index 6aeb3a7..0000000
--- a/app/controllers/IndexController.php
+++ /dev/null
@@ -1,13 +0,0 @@
-save(
- $this->request->getPost(),
- array('name', 'email')
- );
-
- if ($success) {
- echo "Thanks for registering!";
- } else {
- echo "Sorry, the following problems were generated: ";
- foreach ($user->getMessages() as $message) {
- echo $message->getMessage(), "
";
- }
- }
-
- $this->view->disable();
- }
-
-}
diff --git a/app/views/index/index.phtml b/app/views/index/index.phtml
deleted file mode 100644
index 1882ce8..0000000
--- a/app/views/index/index.phtml
+++ /dev/null
@@ -1,6 +0,0 @@
-Hello!";
-
-echo $this->tag->linkTo("signup", "Sign Up Here!");
-
diff --git a/app/views/signup/index.phtml b/app/views/signup/index.phtml
deleted file mode 100644
index 714b41f..0000000
--- a/app/views/signup/index.phtml
+++ /dev/null
@@ -1,19 +0,0 @@
-
Sign using this form
-
-tag->form('signup/register') ?>
-
-
-
- tag->textField("name") ?>
-
-
-
-
- tag->textField("email") ?>
-
-
-
- tag->submitButton("Register") ?>
-
-
-
diff --git a/bin/import_db.sh b/bin/import_db.sh
new file mode 100644
index 0000000..adc257a
--- /dev/null
+++ b/bin/import_db.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+mysql --user=$DATA_MYSQL_USER \
+ --password=$DATA_MYSQL_PASS \
+ --host=$DATA_MYSQL_HOST \
+ phalcon_tutorial < /code/resources/schemas/tutorial.sql
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..cb8c5f7
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,37 @@
+{
+ "name": "phalcon/tutorial",
+ "type": "library",
+ "description": "This is a sample application for the Phalcon PHP Framework",
+ "keywords": [
+ "phalcon",
+ "framework",
+ "sample app",
+ "tytiruak"
+ ],
+ "homepage": "https://phalcon.io",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Phalcon Team",
+ "homepage": "https://github.com/phalcon"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/phalcon/tutorial/graphs/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.0",
+ "ext-openssl": "*",
+ "ext-phalcon": "^5.0.0",
+ "pds/skeleton": "^1.0"
+ },
+ "require-dev": {
+ "phalcon/ide-stubs": "^v5.0.1"
+ },
+ "autoload": {
+ "psr-4": {
+ "Tutorial\\": "src/"
+ }
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..2c077d6
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,126 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "536b46f412f983bc807f32f6289a6a12",
+ "packages": [
+ {
+ "name": "pds/skeleton",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-pds/skeleton.git",
+ "reference": "95e476e5d629eadacbd721c5a9553e537514a231"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-pds/skeleton/zipball/95e476e5d629eadacbd721c5a9553e537514a231",
+ "reference": "95e476e5d629eadacbd721c5a9553e537514a231",
+ "shasum": ""
+ },
+ "bin": [
+ "bin/pds-skeleton"
+ ],
+ "type": "standard",
+ "autoload": {
+ "psr-4": {
+ "Pds\\Skeleton\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "CC-BY-SA-4.0"
+ ],
+ "description": "Standard for PHP package skeletons.",
+ "homepage": "https://github.com/php-pds/skeleton",
+ "support": {
+ "issues": "https://github.com/php-pds/skeleton/issues",
+ "source": "https://github.com/php-pds/skeleton/tree/1.x"
+ },
+ "time": "2017-01-25T23:30:41+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "phalcon/ide-stubs",
+ "version": "v5.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phalcon/ide-stubs.git",
+ "reference": "0593372dcf90d311f5f861a67b0438cc44d29a23"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phalcon/ide-stubs/zipball/0593372dcf90d311f5f861a67b0438cc44d29a23",
+ "reference": "0593372dcf90d311f5f861a67b0438cc44d29a23",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4"
+ },
+ "require-dev": {
+ "squizlabs/php_codesniffer": "3.*",
+ "vimeo/psalm": "^3.4"
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Phalcon Team",
+ "email": "team@phalcon.io",
+ "homepage": "https://phalcon.io/en-us/team"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/phalcon/ide-stubs/graphs/contributors"
+ }
+ ],
+ "description": "The most complete Phalcon Framework IDE stubs library which enables autocompletion in modern IDEs.",
+ "homepage": "https://phalcon.io",
+ "keywords": [
+ "Devtools",
+ "Eclipse",
+ "autocomplete",
+ "ide",
+ "netbeans",
+ "phalcon",
+ "phpstorm",
+ "stub",
+ "stubs"
+ ],
+ "support": {
+ "forum": "https://forum.phalcon.io/",
+ "issues": "https://github.com/phalcon/ide-stubs/issues",
+ "source": "https://github.com/phalcon/ide-stubs"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/phalcon",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/phalcon",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2024-01-09T23:54:03+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=8.0",
+ "ext-openssl": "*",
+ "ext-phalcon": "^5.0.0"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.6.0"
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..06479d6
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,76 @@
+version: '3'
+services:
+
+ # Application - Vökuró
+ tutorial-8.0:
+ build: resources/docker/8.0
+ container_name: tutorial-8.0
+ tty: true
+ working_dir: /code
+ depends_on:
+ - tutorial-mysql
+ volumes:
+ - ./:/code
+ networks:
+ - tutorial-network
+
+ tutorial-8.1:
+ build: resources/docker/8.1
+ container_name: tutorial-8.1
+ tty: true
+ working_dir: /code
+ depends_on:
+ - tutorial-mysql
+ volumes:
+ - ./:/code
+ networks:
+ - tutorial-network
+
+ tutorial-8.2:
+ build: resources/docker/8.2
+ container_name: tutorial-8.2
+ tty: true
+ working_dir: /code
+ depends_on:
+ - tutorial-mysql
+ volumes:
+ - ./:/code
+ networks:
+ - tutorial-network
+
+ tutorial-8.3:
+ build: resources/docker/8.3
+ container_name: tutorial-8.3
+ tty: true
+ working_dir: /code
+ depends_on:
+ - tutorial-mysql
+ volumes:
+ - ./:/code
+ networks:
+ - tutorial-network
+
+ # Database - Mysql
+ tutorial-mysql:
+ image: mysql:5.7
+ container_name: tutorial-mysql
+ tty: true
+ environment:
+ - MYSQL_ROOT_PASSWORD=secret
+ - MYSQL_USER=phalcon
+ - MYSQL_DATABASE=phalcon_tutorial
+ - MYSQL_PASSWORD=secret
+ volumes:
+ - tutorial-volume:/var/lib/mysql/
+ networks:
+ - tutorial-network
+
+# Network
+networks:
+ tutorial-network:
+ driver: bridge
+
+# Volumes
+volumes:
+ tutorial-volume:
+ driver: local
diff --git a/docs/LICENSE.md b/docs/LICENSE.md
deleted file mode 100644
index bfc6075..0000000
--- a/docs/LICENSE.md
+++ /dev/null
@@ -1,13 +0,0 @@
-New BSD License
-===============
-
-Copyright (c) 2013-2015, Phalcon Framework Team and contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-* Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/docs/LICENSE.txt b/docs/LICENSE.txt
deleted file mode 100644
index 2232f8e..0000000
--- a/docs/LICENSE.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-New BSD License
-
-Copyright (c) 2013-2015, Phalcon Framework Team and contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/public/.htaccess b/public/.htaccess
old mode 100755
new mode 100644
index 7a9d6fe..5fe17fa
--- a/public/.htaccess
+++ b/public/.htaccess
@@ -3,5 +3,5 @@ AddDefaultCharset UTF-8
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
- RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
+ RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L]
diff --git a/public/index.php b/public/index.php
old mode 100755
new mode 100644
index 296a030..1819253
--- a/public/index.php
+++ b/public/index.php
@@ -1,61 +1,61 @@
setDirectories(
+ [
+ APP_PATH . '/controllers/',
+ APP_PATH . '/models/',
+ ]
+ )
+ ->register()
+;
+
+// Create a DI
+$container = new FactoryDefault();
+
+// Setting up the view component
+$container['view'] = function () {
+ $view = new View();
+ $view->setViewsDir(APP_PATH . '/views/');
+ return $view;
+};
+
+// Setup a base URI so that all generated URIs include the "tutorial" folder
+$container['url'] = function () {
+ $url = new UrlProvider();
+ $url->setBaseUri('/');
+ return $url;
+};
+
+// Set the database service
+$container['db'] = function () {
+ return new DbAdapter(
+ [
+ "host" => 'tutorial-mysql',
+ "username" => 'phalcon',
+ "password" => 'secret',
+ "dbname" => 'phalcon_tutorial',
+ ]
+ );
+};
+
+// Handle the request
try {
-
- // Register an autoloader
- $loader = new Loader();
- $loader->registerDirs(
- array(
- '../app/controllers/',
- '../app/models/'
- )
- )->register();
-
- // Create a DI
- $di = new FactoryDefault();
-
- // Set the database service
- $di['db'] = function() {
- return new DbAdapter(array(
- "host" => "localhost",
- "username" => "root",
- "password" => "secret",
- "dbname" => "tutorial"
- ));
- };
-
- // Setting up the view component
- $di['view'] = function() {
- $view = new View();
- $view->setViewsDir('../app/views/');
- return $view;
- };
-
- // Setup a base URI so that all generated URIs include the "tutorial" folder
- $di['url'] = function() {
- $url = new Url();
- $url->setBaseUri('/tutorial/');
- return $url;
- };
-
- // Setup the tag helpers
- $di['tag'] = function() {
- return new Tag();
- };
-
- // Handle the request
- $application = new Application($di);
-
- echo $application->handle()->getContent();
-
+ $application = new Application($container);
+ $response = $application->handle($_SERVER["REQUEST_URI"]);
+ $response->send();
} catch (Exception $e) {
- echo "Exception: ", $e->getMessage();
+ echo "Exception: ", $e->getMessage();
}
diff --git a/resources/docker/8.0/Dockerfile b/resources/docker/8.0/Dockerfile
new file mode 100644
index 0000000..8adf485
--- /dev/null
+++ b/resources/docker/8.0/Dockerfile
@@ -0,0 +1,68 @@
+FROM composer:latest as composer
+FROM php:8.0-fpm
+
+COPY ./config/extra.ini /usr/local/etc/php/conf.d/
+
+# Set working directory
+WORKDIR /code
+
+LABEL vendor="Phalcon" \
+ maintainer="Phalcon Team " \
+ description="The PHP image to test the tutorial application"
+
+ENV PHALCON_VERSION="5.6.0"
+
+# Update
+RUN apt update -y && \
+ apt install -y \
+ apt-utils \
+ gettext \
+ git \
+ libzip-dev \
+ nano \
+ sudo \
+ wget \
+ zip
+
+# PECL Packages
+RUN pecl install phalcon-${PHALCON_VERSION} \
+ xdebug
+
+# Install PHP extensions
+RUN docker-php-ext-install \
+ gettext \
+ pdo_mysql \
+ zip
+
+# Install PHP extensions
+RUN docker-php-ext-enable \
+ opcache \
+ phalcon \
+ xdebug
+
+# Clear cache
+RUN apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Add user
+RUN groupadd -g 1000 phalcon
+RUN useradd -u 1000 -ms /bin/bash -g phalcon phalcon
+
+# Composer
+COPY --from=composer /usr/bin/composer /usr/local/bin/composer
+
+# Copy existing application directory contents
+COPY . /code
+
+# Bash script with helper aliases
+COPY ./config/.bashrc /root/.bashrc
+COPY ./config/.bashrc /home/phalcon/.bashrc
+
+# Copy existing application directory permissions
+COPY --chown=phalcon:phalcon . /code
+
+# Change current user to phalcon
+USER phalcon
+
+EXPOSE 80
+
+CMD ["php", "-S", "0.0.0.0:80", "-t", "public/", ".htrouter.php"]
diff --git a/resources/docker/8.0/config/.bashrc b/resources/docker/8.0/config/.bashrc
new file mode 100644
index 0000000..e106a75
--- /dev/null
+++ b/resources/docker/8.0/config/.bashrc
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+# Easier navigation: .., ..., ...., ....., ~ and -
+alias ..="cd .."
+alias ...="cd ../.."
+alias ....="cd ../../.."
+alias .....="cd ../../../.."
+alias ~="cd ~" # `cd` is probably faster to type though
+alias -- -="cd -"
+
+# Shortcuts
+alias g="git"
+alias h="history"
+
+# Detect which `ls` flavor is in use
+if ls --color > /dev/null 2>&1; then # GNU `ls`
+ colorflag="--color"
+else # OS X `ls`
+ colorflag="-G"
+fi
+
+# List all files colorized in long format
+# shellcheck disable=SC2139
+alias l="ls -lF ${colorflag}"
+
+# List all files colorized in long format, including dot files
+# shellcheck disable=SC2139
+alias la="ls -laF ${colorflag}"
+
+# List only directories
+# shellcheck disable=SC2139
+alias lsd="ls -lF ${colorflag} | grep --color=never '^d'"
+
+# See: https://superuser.com/a/656746/280737
+alias ll='LC_ALL="C.UTF-8" ls -alF'
+
+# Always use color output for `ls`
+# shellcheck disable=SC2139
+alias ls="command ls ${colorflag}"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:'
+
+# Always enable colored `grep` output
+alias grep='grep --color=auto '
+
+# Enable aliases to be sudo’ed
+alias sudo='sudo '
+
+# Get week number
+alias week='date +%V'
+
+# Stopwatch
+alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date'
+
+# Canonical hex dump; some systems have this symlinked
+command -v hd > /dev/null || alias hd="hexdump -C"
+
+# vhosts
+alias hosts='sudo nano /etc/hosts'
+
+# copy working directory
+alias cwd='pwd | tr -d "\r\n" | xclip -selection clipboard'
+
+# copy file interactive
+alias cp='cp -i'
+
+# move file interactive
+alias mv='mv -i'
+
+# untar
+alias untar='tar xvf'
+
+# Zephir related
+alias untar='tar xvf'
+
+PATH=$PATH:./vendor/bin
diff --git a/resources/docker/8.0/config/extra.ini b/resources/docker/8.0/config/extra.ini
new file mode 100644
index 0000000..576ff1b
--- /dev/null
+++ b/resources/docker/8.0/config/extra.ini
@@ -0,0 +1,27 @@
+error_reporting = E_ALL
+display_errors = "On"
+display_startup_errors = "On"
+log_errors = "On"
+error_log = /code/php_errors.log
+memory_limit = 512M
+apc.enable_cli = "On"
+session.save_path = "/tmp"
+
+;xdebug
+xdebug.client_host = "localhost"
+xdebug.client_port = 9090
+xdebug.discover_client_host = 1
+xdebug.force_display_errors = 0
+xdebug.force_error_reporting = 0
+xdebug.max_nesting_level = 256
+xdebug.mode = coverage, debug, develop
+xdebug.output_dir = "/tmp"
+xdebug.remote_cookie_expire_time = 3600
+xdebug.remote_mode = "req"
+xdebug.show_error_trace = 1
+xdebug.show_exception_trace = 1
+xdebug.show_local_vars = 1
+xdebug.start_with_request = yes
+xdebug.var_display_max_children = 128
+xdebug.var_display_max_data = 512
+xdebug.var_display_max_depth = 3
diff --git a/resources/docker/8.1/Dockerfile b/resources/docker/8.1/Dockerfile
new file mode 100644
index 0000000..bff12c5
--- /dev/null
+++ b/resources/docker/8.1/Dockerfile
@@ -0,0 +1,68 @@
+FROM composer:latest as composer
+FROM php:8.1-fpm
+
+COPY ./config/extra.ini /usr/local/etc/php/conf.d/
+
+# Set working directory
+WORKDIR /code
+
+LABEL vendor="Phalcon" \
+ maintainer="Phalcon Team " \
+ description="The PHP image to test the tutorial application"
+
+ENV PHALCON_VERSION="5.6.0"
+
+# Update
+RUN apt update -y && \
+ apt install -y \
+ apt-utils \
+ gettext \
+ git \
+ libzip-dev \
+ nano \
+ sudo \
+ wget \
+ zip
+
+# PECL Packages
+RUN pecl install phalcon-${PHALCON_VERSION} \
+ xdebug
+
+# Install PHP extensions
+RUN docker-php-ext-install \
+ gettext \
+ pdo_mysql \
+ zip
+
+# Install PHP extensions
+RUN docker-php-ext-enable \
+ opcache \
+ phalcon \
+ xdebug
+
+# Clear cache
+RUN apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Add user
+RUN groupadd -g 1000 phalcon
+RUN useradd -u 1000 -ms /bin/bash -g phalcon phalcon
+
+# Composer
+COPY --from=composer /usr/bin/composer /usr/local/bin/composer
+
+# Copy existing application directory contents
+COPY . /code
+
+# Bash script with helper aliases
+COPY config/.bashrc /root/.bashrc
+COPY config/.bashrc /home/phalcon/.bashrc
+
+# Copy existing application directory permissions
+COPY --chown=phalcon:phalcon . /code
+
+# Change current user to phalcon
+USER phalcon
+
+EXPOSE 80
+
+CMD ["php", "-S", "0.0.0.0:80", "-t", "public/", ".htrouter.php"]
diff --git a/resources/docker/8.1/config/.bashrc b/resources/docker/8.1/config/.bashrc
new file mode 100644
index 0000000..e106a75
--- /dev/null
+++ b/resources/docker/8.1/config/.bashrc
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+# Easier navigation: .., ..., ...., ....., ~ and -
+alias ..="cd .."
+alias ...="cd ../.."
+alias ....="cd ../../.."
+alias .....="cd ../../../.."
+alias ~="cd ~" # `cd` is probably faster to type though
+alias -- -="cd -"
+
+# Shortcuts
+alias g="git"
+alias h="history"
+
+# Detect which `ls` flavor is in use
+if ls --color > /dev/null 2>&1; then # GNU `ls`
+ colorflag="--color"
+else # OS X `ls`
+ colorflag="-G"
+fi
+
+# List all files colorized in long format
+# shellcheck disable=SC2139
+alias l="ls -lF ${colorflag}"
+
+# List all files colorized in long format, including dot files
+# shellcheck disable=SC2139
+alias la="ls -laF ${colorflag}"
+
+# List only directories
+# shellcheck disable=SC2139
+alias lsd="ls -lF ${colorflag} | grep --color=never '^d'"
+
+# See: https://superuser.com/a/656746/280737
+alias ll='LC_ALL="C.UTF-8" ls -alF'
+
+# Always use color output for `ls`
+# shellcheck disable=SC2139
+alias ls="command ls ${colorflag}"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:'
+
+# Always enable colored `grep` output
+alias grep='grep --color=auto '
+
+# Enable aliases to be sudo’ed
+alias sudo='sudo '
+
+# Get week number
+alias week='date +%V'
+
+# Stopwatch
+alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date'
+
+# Canonical hex dump; some systems have this symlinked
+command -v hd > /dev/null || alias hd="hexdump -C"
+
+# vhosts
+alias hosts='sudo nano /etc/hosts'
+
+# copy working directory
+alias cwd='pwd | tr -d "\r\n" | xclip -selection clipboard'
+
+# copy file interactive
+alias cp='cp -i'
+
+# move file interactive
+alias mv='mv -i'
+
+# untar
+alias untar='tar xvf'
+
+# Zephir related
+alias untar='tar xvf'
+
+PATH=$PATH:./vendor/bin
diff --git a/resources/docker/8.1/config/extra.ini b/resources/docker/8.1/config/extra.ini
new file mode 100644
index 0000000..576ff1b
--- /dev/null
+++ b/resources/docker/8.1/config/extra.ini
@@ -0,0 +1,27 @@
+error_reporting = E_ALL
+display_errors = "On"
+display_startup_errors = "On"
+log_errors = "On"
+error_log = /code/php_errors.log
+memory_limit = 512M
+apc.enable_cli = "On"
+session.save_path = "/tmp"
+
+;xdebug
+xdebug.client_host = "localhost"
+xdebug.client_port = 9090
+xdebug.discover_client_host = 1
+xdebug.force_display_errors = 0
+xdebug.force_error_reporting = 0
+xdebug.max_nesting_level = 256
+xdebug.mode = coverage, debug, develop
+xdebug.output_dir = "/tmp"
+xdebug.remote_cookie_expire_time = 3600
+xdebug.remote_mode = "req"
+xdebug.show_error_trace = 1
+xdebug.show_exception_trace = 1
+xdebug.show_local_vars = 1
+xdebug.start_with_request = yes
+xdebug.var_display_max_children = 128
+xdebug.var_display_max_data = 512
+xdebug.var_display_max_depth = 3
diff --git a/resources/docker/8.2/Dockerfile b/resources/docker/8.2/Dockerfile
new file mode 100644
index 0000000..7ee6627
--- /dev/null
+++ b/resources/docker/8.2/Dockerfile
@@ -0,0 +1,68 @@
+FROM composer:latest as composer
+FROM php:8.2-fpm
+
+COPY ./config/extra.ini /usr/local/etc/php/conf.d/
+
+# Set working directory
+WORKDIR /code
+
+LABEL vendor="Phalcon" \
+ maintainer="Phalcon Team " \
+ description="The PHP image to test the tutorial application"
+
+ENV PHALCON_VERSION="5.6.0"
+
+# Update
+RUN apt update -y && \
+ apt install -y \
+ apt-utils \
+ gettext \
+ git \
+ libzip-dev \
+ nano \
+ sudo \
+ wget \
+ zip
+
+# PECL Packages
+RUN pecl install phalcon-${PHALCON_VERSION} \
+ xdebug
+
+# Install PHP extensions
+RUN docker-php-ext-install \
+ gettext \
+ pdo_mysql \
+ zip
+
+# Install PHP extensions
+RUN docker-php-ext-enable \
+ opcache \
+ phalcon \
+ xdebug
+
+# Clear cache
+RUN apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Add user
+RUN groupadd -g 1000 phalcon
+RUN useradd -u 1000 -ms /bin/bash -g phalcon phalcon
+
+# Composer
+COPY --from=composer /usr/bin/composer /usr/local/bin/composer
+
+# Copy existing application directory contents
+COPY . /code
+
+# Bash script with helper aliases
+COPY config/.bashrc /root/.bashrc
+COPY config/.bashrc /home/phalcon/.bashrc
+
+# Copy existing application directory permissions
+COPY --chown=phalcon:phalcon . /code
+
+# Change current user to phalcon
+USER phalcon
+
+EXPOSE 80
+
+CMD ["php", "-S", "0.0.0.0:80", "-t", "public/", ".htrouter.php"]
diff --git a/resources/docker/8.2/config/.bashrc b/resources/docker/8.2/config/.bashrc
new file mode 100644
index 0000000..e106a75
--- /dev/null
+++ b/resources/docker/8.2/config/.bashrc
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+# Easier navigation: .., ..., ...., ....., ~ and -
+alias ..="cd .."
+alias ...="cd ../.."
+alias ....="cd ../../.."
+alias .....="cd ../../../.."
+alias ~="cd ~" # `cd` is probably faster to type though
+alias -- -="cd -"
+
+# Shortcuts
+alias g="git"
+alias h="history"
+
+# Detect which `ls` flavor is in use
+if ls --color > /dev/null 2>&1; then # GNU `ls`
+ colorflag="--color"
+else # OS X `ls`
+ colorflag="-G"
+fi
+
+# List all files colorized in long format
+# shellcheck disable=SC2139
+alias l="ls -lF ${colorflag}"
+
+# List all files colorized in long format, including dot files
+# shellcheck disable=SC2139
+alias la="ls -laF ${colorflag}"
+
+# List only directories
+# shellcheck disable=SC2139
+alias lsd="ls -lF ${colorflag} | grep --color=never '^d'"
+
+# See: https://superuser.com/a/656746/280737
+alias ll='LC_ALL="C.UTF-8" ls -alF'
+
+# Always use color output for `ls`
+# shellcheck disable=SC2139
+alias ls="command ls ${colorflag}"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:'
+
+# Always enable colored `grep` output
+alias grep='grep --color=auto '
+
+# Enable aliases to be sudo’ed
+alias sudo='sudo '
+
+# Get week number
+alias week='date +%V'
+
+# Stopwatch
+alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date'
+
+# Canonical hex dump; some systems have this symlinked
+command -v hd > /dev/null || alias hd="hexdump -C"
+
+# vhosts
+alias hosts='sudo nano /etc/hosts'
+
+# copy working directory
+alias cwd='pwd | tr -d "\r\n" | xclip -selection clipboard'
+
+# copy file interactive
+alias cp='cp -i'
+
+# move file interactive
+alias mv='mv -i'
+
+# untar
+alias untar='tar xvf'
+
+# Zephir related
+alias untar='tar xvf'
+
+PATH=$PATH:./vendor/bin
diff --git a/resources/docker/8.2/config/extra.ini b/resources/docker/8.2/config/extra.ini
new file mode 100644
index 0000000..576ff1b
--- /dev/null
+++ b/resources/docker/8.2/config/extra.ini
@@ -0,0 +1,27 @@
+error_reporting = E_ALL
+display_errors = "On"
+display_startup_errors = "On"
+log_errors = "On"
+error_log = /code/php_errors.log
+memory_limit = 512M
+apc.enable_cli = "On"
+session.save_path = "/tmp"
+
+;xdebug
+xdebug.client_host = "localhost"
+xdebug.client_port = 9090
+xdebug.discover_client_host = 1
+xdebug.force_display_errors = 0
+xdebug.force_error_reporting = 0
+xdebug.max_nesting_level = 256
+xdebug.mode = coverage, debug, develop
+xdebug.output_dir = "/tmp"
+xdebug.remote_cookie_expire_time = 3600
+xdebug.remote_mode = "req"
+xdebug.show_error_trace = 1
+xdebug.show_exception_trace = 1
+xdebug.show_local_vars = 1
+xdebug.start_with_request = yes
+xdebug.var_display_max_children = 128
+xdebug.var_display_max_data = 512
+xdebug.var_display_max_depth = 3
diff --git a/resources/docker/8.3/Dockerfile b/resources/docker/8.3/Dockerfile
new file mode 100644
index 0000000..2d10787
--- /dev/null
+++ b/resources/docker/8.3/Dockerfile
@@ -0,0 +1,68 @@
+FROM composer:latest as composer
+FROM php:8.3-fpm
+
+COPY ./config/extra.ini /usr/local/etc/php/conf.d/
+
+# Set working directory
+WORKDIR /code
+
+LABEL vendor="Phalcon" \
+ maintainer="Phalcon Team " \
+ description="The PHP image to test the tutorial application"
+
+ENV PHALCON_VERSION="5.6.0"
+
+# Update
+RUN apt update -y && \
+ apt install -y \
+ apt-utils \
+ gettext \
+ git \
+ libzip-dev \
+ nano \
+ sudo \
+ wget \
+ zip
+
+# PECL Packages
+RUN pecl install phalcon-${PHALCON_VERSION} \
+ xdebug
+
+# Install PHP extensions
+RUN docker-php-ext-install \
+ gettext \
+ pdo_mysql \
+ zip
+
+# Install PHP extensions
+RUN docker-php-ext-enable \
+ opcache \
+ phalcon \
+ xdebug
+
+# Clear cache
+RUN apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Add user
+RUN groupadd -g 1000 phalcon
+RUN useradd -u 1000 -ms /bin/bash -g phalcon phalcon
+
+# Composer
+COPY --from=composer /usr/bin/composer /usr/local/bin/composer
+
+# Copy existing application directory contents
+COPY . /code
+
+# Bash script with helper aliases
+COPY config/.bashrc /root/.bashrc
+COPY config/.bashrc /home/phalcon/.bashrc
+
+# Copy existing application directory permissions
+COPY --chown=phalcon:phalcon . /code
+
+# Change current user to phalcon
+USER phalcon
+
+EXPOSE 80
+
+CMD ["php", "-S", "0.0.0.0:80", "-t", "public/", ".htrouter.php"]
diff --git a/resources/docker/8.3/config/.bashrc b/resources/docker/8.3/config/.bashrc
new file mode 100644
index 0000000..e106a75
--- /dev/null
+++ b/resources/docker/8.3/config/.bashrc
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+# Easier navigation: .., ..., ...., ....., ~ and -
+alias ..="cd .."
+alias ...="cd ../.."
+alias ....="cd ../../.."
+alias .....="cd ../../../.."
+alias ~="cd ~" # `cd` is probably faster to type though
+alias -- -="cd -"
+
+# Shortcuts
+alias g="git"
+alias h="history"
+
+# Detect which `ls` flavor is in use
+if ls --color > /dev/null 2>&1; then # GNU `ls`
+ colorflag="--color"
+else # OS X `ls`
+ colorflag="-G"
+fi
+
+# List all files colorized in long format
+# shellcheck disable=SC2139
+alias l="ls -lF ${colorflag}"
+
+# List all files colorized in long format, including dot files
+# shellcheck disable=SC2139
+alias la="ls -laF ${colorflag}"
+
+# List only directories
+# shellcheck disable=SC2139
+alias lsd="ls -lF ${colorflag} | grep --color=never '^d'"
+
+# See: https://superuser.com/a/656746/280737
+alias ll='LC_ALL="C.UTF-8" ls -alF'
+
+# Always use color output for `ls`
+# shellcheck disable=SC2139
+alias ls="command ls ${colorflag}"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:'
+
+# Always enable colored `grep` output
+alias grep='grep --color=auto '
+
+# Enable aliases to be sudo’ed
+alias sudo='sudo '
+
+# Get week number
+alias week='date +%V'
+
+# Stopwatch
+alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date'
+
+# Canonical hex dump; some systems have this symlinked
+command -v hd > /dev/null || alias hd="hexdump -C"
+
+# vhosts
+alias hosts='sudo nano /etc/hosts'
+
+# copy working directory
+alias cwd='pwd | tr -d "\r\n" | xclip -selection clipboard'
+
+# copy file interactive
+alias cp='cp -i'
+
+# move file interactive
+alias mv='mv -i'
+
+# untar
+alias untar='tar xvf'
+
+# Zephir related
+alias untar='tar xvf'
+
+PATH=$PATH:./vendor/bin
diff --git a/resources/docker/8.3/config/extra.ini b/resources/docker/8.3/config/extra.ini
new file mode 100644
index 0000000..576ff1b
--- /dev/null
+++ b/resources/docker/8.3/config/extra.ini
@@ -0,0 +1,27 @@
+error_reporting = E_ALL
+display_errors = "On"
+display_startup_errors = "On"
+log_errors = "On"
+error_log = /code/php_errors.log
+memory_limit = 512M
+apc.enable_cli = "On"
+session.save_path = "/tmp"
+
+;xdebug
+xdebug.client_host = "localhost"
+xdebug.client_port = 9090
+xdebug.discover_client_host = 1
+xdebug.force_display_errors = 0
+xdebug.force_error_reporting = 0
+xdebug.max_nesting_level = 256
+xdebug.mode = coverage, debug, develop
+xdebug.output_dir = "/tmp"
+xdebug.remote_cookie_expire_time = 3600
+xdebug.remote_mode = "req"
+xdebug.show_error_trace = 1
+xdebug.show_exception_trace = 1
+xdebug.show_local_vars = 1
+xdebug.start_with_request = yes
+xdebug.var_display_max_children = 128
+xdebug.var_display_max_data = 512
+xdebug.var_display_max_depth = 3
diff --git a/schemas/tutorial.sql b/resources/schemas/tutorial.sql
similarity index 62%
rename from schemas/tutorial.sql
rename to resources/schemas/tutorial.sql
index 44f6f06..4f8cede 100644
--- a/schemas/tutorial.sql
+++ b/resources/schemas/tutorial.sql
@@ -1,13 +1,10 @@
--- MySQL dump 10.13 Distrib 5.5.36, for osx10.9 (i386)
---
--- Host: localhost Database: tutorial
--- ------------------------------------------------------
--- Server version 5.5.36
+CREATE DATABASE IF NOT EXISTS `tutorial` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
+USE `tutorial`;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
+/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
@@ -19,27 +16,19 @@
-- Table structure for table `users`
--
-DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `users` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(70) NOT NULL,
- `email` varchar(70) NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40101 SET character_set_client = utf8mb4 */;
+CREATE TABLE `users`
+(
+ `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Record ID',
+ `name` varchar(255) NOT NULL COMMENT 'User Name',
+ `email` varchar(255) NOT NULL COMMENT 'User Email Address',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
---
--- Dumping data for table `users`
---
+/*!40101 SET character_set_client = @saved_cs_client */;
-LOCK TABLES `users` WRITE;
-/*!40000 ALTER TABLE `users` DISABLE KEYS */;
-/*!40000 ALTER TABLE `users` ENABLE KEYS */;
-UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
-
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
@@ -48,4 +37,5 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2014-08-26 14:20:40
+INSERT INTO `users` (`name`, `email`)
+VALUES ('Phalcon Team', 'team@phalcon.io');
diff --git a/src/controllers/IndexController.php b/src/controllers/IndexController.php
new file mode 100644
index 0000000..af1d3f7
--- /dev/null
+++ b/src/controllers/IndexController.php
@@ -0,0 +1,14 @@
+view->users = Users::find();
+ }
+}
diff --git a/src/controllers/SignupController.php b/src/controllers/SignupController.php
new file mode 100644
index 0000000..31f5e41
--- /dev/null
+++ b/src/controllers/SignupController.php
@@ -0,0 +1,41 @@
+request->getPost();
+
+ // Store and check for errors
+ $user = new Users();
+ $user->name = $post['name'];
+ $user->email = $post['email'];
+ // Store and check for errors
+ $success = $user->save();
+
+ // passing the result to the view
+ $this->view->success = $success;
+
+ if ($success) {
+ $message = "Thanks for registering!";
+ } else {
+ $message = "Sorry, the following problems were generated:
"
+ . implode('
', $user->getMessages());
+ }
+
+ // passing a message to the view
+ $this->view->message = $message;
+ }
+}
diff --git a/app/models/Users.php b/src/models/Users.php
similarity index 53%
rename from app/models/Users.php
rename to src/models/Users.php
index 7e9e3f4..4081bf7 100644
--- a/app/models/Users.php
+++ b/src/models/Users.php
@@ -4,11 +4,7 @@
class Users extends Model
{
-
- public $id;
-
- public $name;
-
- public $email;
-
+ public $email;
+ public $id;
+ public $name;
}
diff --git a/src/views/index.phtml b/src/views/index.phtml
new file mode 100644
index 0000000..116ee8f
--- /dev/null
+++ b/src/views/index.phtml
@@ -0,0 +1,14 @@
+
+
+
+
+ Phalcon Tutorial
+
+
+
+
+ getContent(); ?>
+
+
+
diff --git a/src/views/index/index.phtml b/src/views/index/index.phtml
new file mode 100644
index 0000000..d068078
--- /dev/null
+++ b/src/views/index/index.phtml
@@ -0,0 +1,33 @@
+Hello!";
+
+echo $this->tag->a('signup', 'Sign Up Here!', ['class' => 'btn btn-primary']);
+
+if ($users->count() > 0) {
+ ?>
+
+
+
+ | # |
+ Name |
+ Email |
+
+
+
+
+ | Users quantity: count(); ?> |
+
+
+
+
+
+ | id; ?> |
+ name; ?> |
+ email; ?> |
+
+
+
+
+ Sign using this form
+
+tag->form(['action' => '/signup/register']); ?>
+
+
+
+ tag->inputText('name'); ?>
+
+
+
+
+ tag->inputText('email'); ?>
+
+
+
+ tag->inputSubmit('Register', null, ['class' => 'btn btn-primary']); ?>
+
+
+tag->close('form'); ?>
diff --git a/src/views/signup/register.phtml b/src/views/signup/register.phtml
new file mode 100644
index 0000000..9edcdaa
--- /dev/null
+++ b/src/views/signup/register.phtml
@@ -0,0 +1,5 @@
+
+
+
+
+tag->a('/', 'Go back', ['class' => 'btn btn-primary']); ?>