├── .gitignore
├── .htaccess
├── README.md
├── application
├── controller
│ ├── Debug.php
│ ├── Doc.php
│ ├── Home.php
│ └── index.html
├── index.html
├── model
│ └── index.html
└── view
│ ├── 401.php
│ ├── 404.php
│ ├── docs
│ └── index.php
│ ├── home
│ └── index.php
│ └── index.html
├── cli
├── fmvc
├── index.html
├── lib
│ ├── Environment.php
│ └── Filegen.php
└── templates
│ ├── controller.txt
│ ├── model.txt
│ └── view.txt
├── composer.json
├── config
├── config_template.php
├── development.php
├── environment.php
├── index.html
└── testing.php
├── core
├── bootstrap.php
├── data
│ ├── PdoConn.php
│ └── index.html
├── functions
│ ├── global_functions.php
│ └── index.html
├── helper
│ ├── Documentation.php
│ ├── Escape.php
│ ├── Filter.php
│ ├── HtmlHead.php
│ ├── Logger.php
│ ├── RestApiCaller.php
│ └── index.html
├── index.html
├── lib
│ ├── Config.php
│ ├── Controller.php
│ ├── Input.php
│ └── index.html
└── routes.php
├── data
├── index.html
└── sqlite
│ ├── index.html
│ └── unit_test.db
├── docs
├── command_line.md
├── controllers.md
├── databases.md
├── debugging.md
├── html_head_generator.md
├── index.html
├── input_filtering.md
├── logger.md
├── models.md
├── multiple_environments.md
├── views.md
└── windows_authentication.md
├── humans.txt
├── index.php
├── license.txt
├── tests
├── README.md
├── api_test
│ ├── delete.php
│ ├── get.php
│ ├── post-json.php
│ ├── post-xml.php
│ ├── post.php
│ └── put.php
├── cli
│ ├── CliEnvironmentTest.php
│ └── CliFilegenTest.php
├── core
│ ├── ConfigTest.php
│ ├── ControllerTest.php
│ ├── DocumentationTest.php
│ ├── FilterTest.php
│ ├── HtmlHeadTest.php
│ ├── InputTest.php
│ ├── LoggerTest.php
│ ├── PdoConnTest.php
│ └── RestApiCallerTest.php
└── index.html
├── version.txt
└── web
├── css
├── .htaccess
├── docs.css
└── index.html
├── img
├── .htaccess
└── index.html
├── index.php
└── scripts
├── .htaccess
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | # PACKAGES #
2 | *.phar
3 | *.lock
4 | *.com
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # OS Files #
11 | .DS_Store
12 | .DS_Store?
13 | ._*
14 | .Spotlight-V100
15 | .Trashes
16 | ehthumbs.db
17 | Thumbs.db
18 | .idea/*
19 |
20 | # LOGS / DATABASES #
21 | *.sqlite
22 | *.log
23 | error_log/*
24 | temp/*
25 |
26 | # APP SPECIFIC #
27 | web/scripts/jquery/*
28 | libraries/*
29 | cgi-bin/*
30 | build.xml
31 | tests/temp/*
32 | tests/coverage/*
33 | web.config
34 | php.ini
--------------------------------------------------------------------------------
/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine On
2 | RewriteCond %{REQUEST_FILENAME} !-f
3 | RewriteCond %{REQUEST_FILENAME} !-d
4 | RewriteRule ^(.*)$ index.php [QSA,L]
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Flight MVC
2 |
3 | ## Description
4 | This is my take on a simple extension to implement a more 'classic' MVC pattern that runs on top of the Flight micro-framework. Flight is a great, lightweight framework for PHP. I happen to find it a little easier to work in a more traditional MVC type of structure. This extension of Flight establishes that structure and also adds in a few features like:
5 |
6 | * a PDO wrapper
7 | * a Router to read the controller, command, and 2 parameters
8 | * multiple environments and config files
9 | * a debugger function
10 | * a logger
11 | * an HTML head section builder
12 | * a input filter class (static methods)
13 |
14 | ##Installation
15 | Clone or download this repository and then run Composer's update feature to install dependencies (like Flight!). You can modify the `composer.json` files section on `require-dev` to get rid of or add development libraries like Phing, Codesniffer, phpUnit, etc.
16 |
17 | ## Unit testing
18 | All of the classes in this mod are unit tested with phpUnit, you will find the tests in the /tests directory
19 |
20 | ## Documentation
21 | Documentation for Flight is at: [http://flightphp.com]
22 |
23 | All extension documentation is in the Docs folder. You can also view the documentation using the `doc` controller (e.g. `http://example.com/doc`)
24 |
25 | ## Contributing
26 | Fork this repository and send a pull request. Please stick to issues on the issue tracker or to-do's in the individual files as my intent is to keep this repo as lightweight as possible, and I do not intend to make it a full featured extension of the Flight framework. If you have an idea for a feature, submit it to the issue tracker and let's talk it out before you start coding. I have some ideas too, but some may end up as different extensions rather than features in this extension of Flight. Remember, it is a 'micro-framework' after all.
27 |
28 | ###Conventions
29 | This extension follows PSR-1, PSR-2, and PSR-4 conventions for autoloading, structure, and style. All contributions should follow these conventions. I recommend checking with Codesniffer to be sure.
30 |
31 | ##Thanks/Credits
32 | * Mike Cao: developer of the Flight micro-framework [http://flightphp.com]
33 | * Emanuil Rusev: for the Parsedown Library that runs the doc viewer [http://erusev.com]
34 |
--------------------------------------------------------------------------------
/application/controller/Debug.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2013
9 | * @license /license.txt
10 | */
11 | namespace fmvc\application\controller;
12 |
13 | class Debug extends \fmvc\core\lib\Controller
14 | {
15 | public function __construct($deps, $params)
16 | {
17 | parent::__construct($deps, $params);
18 | }
19 |
20 | /**
21 | * Not used, show 404 error
22 | */
23 | public function index()
24 | {
25 |
26 | \Flight::render('404', array());
27 | }
28 |
29 | /**
30 | * Show PHP Info, but not in production environment
31 | * DELETE THIS METHOD IF YOU DON'T NEED IT
32 | */
33 | public function info()
34 | {
35 | echo \Flight::config()->item('environment');
36 | if (\Flight::config()->item('environment') !== 'production') {
37 | echo phpinfo();
38 | } else {
39 | echo 'DISABLED';
40 | }
41 | }
42 |
43 | /**
44 | * Debug dump of the Controller Object (not in production)
45 | * DELETE THIS METHOD IF YOU DON'T NEED IT
46 | */
47 | public function this()
48 | {
49 | echo "Current Environment: " . \Flight::config()->item('environment') . " ";
50 | if (\Flight::config()->item('environment') !== 'production') {
51 | echo "
Debug of the current controller object
";
52 | debug($this);
53 | } else {
54 | echo 'DISABLED';
55 | }
56 | }
57 |
58 | /**
59 | * Debug dump of the Config Object (not in production)
60 | * DELETE THIS METHOD IF YOU DON'T NEED IT
61 | */
62 | public function config()
63 | {
64 | echo "Current Environment: " . \Flight::config()->item('environment') . " ";
65 | if (\Flight::config()->item('environment') !== 'production') {
66 | echo "
Debug of the current configuration object
";
67 | debug(\Flight::config()->item());
68 | } else {
69 | echo 'DISABLED';
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/application/controller/Doc.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright 2014
11 | * @license /license.txt
12 | */
13 | namespace fmvc\application\controller;
14 |
15 | class Doc extends \fmvc\core\lib\Controller
16 | {
17 |
18 | public function __construct($deps, $params)
19 | {
20 | parent::__construct($deps, $params);
21 |
22 | $this->parser = new \Parsedown();
23 | $this->doc = new \fmvc\core\helper\Documentation();
24 | $this->head->style(array('docs'));
25 | $this->head->title('FlightMVC Documentation Viewer');
26 | }
27 |
28 | public function index()
29 | {
30 | $data = array();
31 |
32 | $data['html_head'] = $this->head->head();
33 | $data['filelist'] = $this->doc->getDocumentationFileNames();
34 |
35 |
36 | if (isset($this->param[0])) {
37 | $data['text'] = $this->doc->parseDocumentationFile($this->param[0].'.md', $this->parser);
38 | } else {
39 | $markdown = file_get_contents('./README.md');
40 | $data['text'] = $this->parser->text($markdown);
41 | }
42 |
43 | \Flight::render('docs/index', $data);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/application/controller/Home.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2014
9 | * @license /license.txt
10 | */
11 | namespace fmvc\application\controller;
12 |
13 | class Home extends \fmvc\core\lib\Controller
14 | {
15 | /**
16 | * Constructor: Dependencies are picked up from routes.php The default
17 | * Dependencies sent to the controller are Config and Input, which are then
18 | * passed through to the parent constructor
19 | * @param array $deps dependencies
20 | * @param array $params parameters passed via the uri
21 | */
22 | public function __construct($deps, $params)
23 | {
24 | parent::__construct($deps, $params);
25 | }
26 |
27 | /**
28 | * Main Menu, Home Page
29 | */
30 | public function index()
31 | {
32 |
33 | \Flight::render('home/index', array('html_head' => $this->head->head()));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/application/controller/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/data/sqlite/unit_test.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndrewPodner/flight-MVC/b6c1a9187655ed1040ba2a61876e57c2b79daf80/data/sqlite/unit_test.db
--------------------------------------------------------------------------------
/docs/command_line.md:
--------------------------------------------------------------------------------
1 | #Flight-MVC Command Line Interface
2 | Flight-MVC has a command line interface to make some tasks more automated in an effort to speed up development and maintenance. The following functions are available from the command line:
3 | * Start or Halt the site
4 | * Set the environment (development, testing, etc.)
5 | * Create a Model file
6 | * Create a Controller file
7 | * Create a View file
8 |
9 | ##Usage:
10 | Call the command line interface (shown here from the `cli` directory) using: `./fmvc commandName parameter1`
11 |
12 | ##Start/Stop and Environment
13 | The `environment` command can be used to start or halt the site as well as change the environment of the application.
14 |
15 | ####Valid Parameters
16 | * halt: inserts code into the `config\environment.php` file that causes the all code to stop executing
17 | * start: restarts the site by removing the halt code
18 | * auto: puts the environment into auto-detect mode
19 | * : you can pass development, testing, or any other valid environment mode you have specified.
20 |
21 | ####Examples
22 | ```
23 | //shut down the site
24 | ./fmvc environment halt
25 |
26 | //start the site from a halt
27 | ./fmvc environment start
28 |
29 | //change to development environment
30 | ./fmvc environment development
31 | ```
32 |
33 | ##Create a model, controller, or view
34 | The command line interface helps to automate the creation of common MVC file to speed up development. From the command line, you can create a new controller, model, or view file that will contain all of the code needed to get each type of object started.
35 |
36 | When creating an object, you can also specify subdirectory (and child namespace for models & controllers) to create the object in. If the subdirectory does not exist, it will be created for you. Additionally, the object generator will also check to see if the file you are trying to create already exists.
37 |
38 | ####Examples:
39 | Create a controller called `Test` in the `application/controller` directory
40 | ```
41 | ./fmvc controller test
42 | ```
43 |
44 | Create a controller called `Test` in the `application/controller/sample` directory
45 | ```
46 | ./fmvc controller sample/test
47 | ```
48 |
49 | Create a model called `Sample` in the `application/model` directory
50 | ```
51 | ./fmvc model sample
52 | ```
53 |
54 | Create a view called main.php in the `view/home` directory
55 | ```
56 | ./fmvc view home/main
57 | ```
58 |
59 |
--------------------------------------------------------------------------------
/docs/controllers.md:
--------------------------------------------------------------------------------
1 | #Using Controllers
2 |
3 | ##General
4 | * All controller classes must extend the `\core\lib\Controller` class
5 | * example: `class Home extends \core\lib\Controller`
6 | * Controllers should typically be located in the `application\controller\` directory and should also be in that namespace as well
7 | * The name of the controller class must be the same as its filename.
8 |
9 | ##Constructor
10 | The constructor of the controller class must call the parent constructor, as shown below
11 | ```
12 | public function __construct($deps, $params)
13 | {
14 | parent::__construct($deps, $params);
15 |
16 | }
17 | ```
18 |
19 | Other code can be added to the constructor (e.g. instantiating a data connection object into a controller class property), but the a call to the parent constructor must be part of the code.
20 |
21 | ##Dependencies
22 | When a controller is called via the URL router, it is automatically loaded with the following dependencies:
23 | * `$this->config`: The current application configuration
24 | * `$this->input` : The object containing superglobals
25 | * `this->head`: The object for managing the HTML head section of a view
26 |
27 | >Note: You can modify how/what the router automatically loads by changing the `/core/routes.php` file around line 52.
28 |
29 | ##Parameters
30 | The router also loads URL parameters into the controller each time it loads. The parameters can be found in the `$this->param` property which is an array. The first parameter is `$param[0]` and the second parameter will be loaded as `$param[1].
31 |
32 | ####Example
33 | ```
34 | http://example.com/home/index/foo/bar
35 |
36 | Controller: Home
37 | Command: index()
38 | $param[0] = 'foo'
39 | $param[1] = 'bar'
40 |
41 | ```
42 | >NOTE: at this time, only 2 parameters are supported.
43 |
44 | ##Commands
45 | Each function (and they need to have public scope) serves a a command in the controller you are working in. For example the URL: `http://example.com/home/index` will call the `index()` function in the `Home` class. Every class should typically have an `index()` command, unless you are certain that this will not be needed. If a URL is specified in a browser which has a controller but no command (e.g. `http://example.com/home`), the app will default to the `index()` command. If there is not one, a 404 error will be displayed.
46 |
47 | ##Working inside a controller command
48 | Within the command, you should be calling data from your models and then rendering it out to a view, or passing it however you want if your application is an API.
49 |
50 | ####Example
51 | ```
52 | public function viewdata()
53 | {
54 | //Open a connection to the data source
55 | $db = new \core\data\PdoConn(array('config' => \Flight::config()));
56 |
57 | //Get an array of all of the data in the companies table
58 | $rs = $db->getAll('companies');
59 |
60 | //Use Flight's rendering method to open the `views/home/viewdata.php`
61 | // view and put the data into the $data variable in the view.
62 | \Flight::render('home/viewdata', array('data' => $rs));
63 | }
64 | ```
65 |
66 |
67 |
--------------------------------------------------------------------------------
/docs/databases.md:
--------------------------------------------------------------------------------
1 | #Working with Databases
2 |
3 | Native support for database connections is managed through a wrapper class for the PDO class. Presently, connections to the following databases are supported in the wrapper. All methods in the wrapper class use prepared statements.
4 | * Mysql
5 | * SQL Server
6 | * ODBC
7 | * Sqlite
8 | * Postgres
9 |
10 | ##Connecting
11 | Connecting to a database is managed via the configuration file. The database configuration resides in a multi-dimensional array where each top level element is the configuration for a data connection (e.g. `$confg['db_default'])
12 |
13 | `db_default` is the fallback connection that will be used if no connection is specified when the `PdoConn` class is instantiated. If a configuration is specified, only the part after the `db_` is passed into the instantiation statement. For instance, if there is a configuration called `$config['db_foo']`, it is called with the following statement:
14 |
15 | ```
16 |
17 | $foo = new \core\data\PdoConn(array('config' => \Flight::config()), 'foo');
18 |
19 | ```
20 | The PDO connection can be directly accessed from the PdoConn object using the `conn` property (e.g. `$foo->conn`)
21 |
22 | The array elements for each type of database vary from platform to platform. The `config/config_template.php` file gives more details as to which elements are needed for each database system.
23 | * Mysql
24 | * driver: 'mysql'
25 | * host
26 | * db_user
27 | * db_password
28 | * db_name
29 | * SQL Server
30 | * driver: 'sqlsrv'
31 | * dsn
32 | * db_user
33 | * db_password
34 | * ODBC
35 | * driver: 'odbc'
36 | * dsn
37 | * db_user
38 | * db_password
39 | * Sqlite
40 | * driver: 'sqlite'
41 | * db_path (if null, `/data/sqlite` is the default path)
42 | * db_filename
43 | * Postgres
44 | * driver: 'pgsql'
45 | * host
46 | * db_user
47 | * db_password
48 | * db_name
49 |
50 | ##Dynamic Methods
51 |
52 | The PdoConn class supports a variety of dynamic method names using the PHP `__call()` magic method. There are 6 database operations supported via dynamic methods. Method names are always in camelCase with the first letter being lowercase (e.g. `getTableByField`). The system converts camelCase to underscores in the database, so your database fields and tables should always be in underscore.
53 |
54 | ####Example
55 | The dynamic method `getCompanyByCompanyName('Example')` would look for an exact match to 'Example' in the `company_name` field of the `company` table.
56 |
57 | >NOTE: you can specify a table prefix in the database configuration, `$config['db_prefix']` such as `ABC_`. If you add a prefix, then the dynamic call to `getCompanyByCompanyName('Example')` would look for the `ABC_company` table.
58 |
59 | * get: This is the basic select method. It accepts 1 parameter, which is the value of the field you are searching. The get method looks for exact matches to whatever parameter is specified. Usage: `$foo->getCompanyByAccountStatus('active')` looks for companies with an account status of active. Results are given in a multidimensional array as follows: `$row[0]['field_name']`
60 |
61 | * filter: This is a select method that accepts and sorts. It accepts 1 parameter, which is the value of the field you are searching. The get method looks for exact matches to whatever parameter is specified. Usage: `$foo->filterCompanyByAccountStatus('act*')` looks for companies with an account status that begins with `act`. Asteriks are used as wildcards. Results are given in a multidimensional array as follows: `$row[0]['field_name']`
62 |
63 | * all: This will retrieve all fields of all rows for the specified table. Usage: `$foo->allCompany()` is the same as saying "SELECT * FROM company";
64 |
65 | * insert: This mimics the SQL insert method. The parameter is a multidimensional array in the form of `$row[0]['field_name'] = 'value'` Each record to be inserted must have the same number of fields. Any number of fields in the table can be part of the insert statement. It returns the last insert id (return value may not work properly in ODBC).
66 |
67 | * update: This mimics the SQL update method. The parameters are 2 arrays, the first array is a the field names and values in the form `$row['field_name']='value'` and the second is an array for the where clause in the form of `$where['field_name']='value'`. Returns the number of affected rows.
68 |
69 | * delete: Works similar to get. Usage: `$foo->deleteCompanyByStatus('inactive')` will delete all companies with the status 'inactive'. Returns the number of affected rows.
70 |
71 | ##Other methods
72 | The get, filter, update, insert, delete, and getAll methods can also be used without calling a dynamic method name. These methods are all documented in the PDOConn class method comments.
73 |
74 | For more complex queries, it is recommended that the PDO connection be called directly using the `conn` propery (e.g. $foo->conn->prepare()). Dynamic methods are provided to reduce the lines of code needed to execute simple CRUD operations.
--------------------------------------------------------------------------------
/docs/debugging.md:
--------------------------------------------------------------------------------
1 | #Debugging
2 |
3 | There is a global function called `debug()` that can be called. It will provide an easily readable view of whatever array / object you are trying to view
4 |
5 | Additionally, there are a few commands in the default `Debug` controller like:
6 | * `this`: shows the debug dump of the Controller object
7 | * `info`: shows `phpinfo()
8 | * `config`: show the debug dump of the config object
9 |
10 | These commands do not work in production mode, but it is highly recommended to delete them from the controller or delete the controller entirely if they are not needed to protect application security.
11 |
12 |
--------------------------------------------------------------------------------
/docs/html_head_generator.md:
--------------------------------------------------------------------------------
1 | #Managing the `` section of an HTML page
2 |
3 | The `` section of your HTML pages can be managed with the HTML Head helper class. This class loads automatically when the controller loads. This helper is designed primarily to manage 3 things:
4 | * Including stylesheets (CSS files)
5 | * Including Javascript files
6 | * Manipulating the `` tag of a page.
7 |
8 | Other tags can be written in to the head section of your pages using views and/or layouts, but as stylesheets, scripts, and titles are often dynamic within the application, support for easy manipulation of these is provided via the helper.
9 |
10 | The default title for the application can be set in the configuration file for each running environment using the `$config['default_title']` element of the configuration array. This will be used if the title is not set at runtime.
11 |
12 | ##Usage
13 | The class expects javascript file to be located in the `./web/scripts` directory, or a subdirectory of it. It also expects javascript files to end in the `.js` file extension. Likewise, stylesheets should be located in the `./web/css` directory (or a subdirectory) and end with the `.css` file extension.
14 |
15 | To use the helper, call the `style()` or `script()` methods and pass an array of filenames (no extension) to the method. If you were trying to load a file in subdirectory, your would prefix the filename with the directory name and a `/` character (e.g. `subdir/file`). You can pass multiple array elements to load multiple script or stylesheet files with a single method call.
16 |
17 | To change the page title, call the `title()` method and use a string for whatever title you want to use.
18 |
19 | ####Let's do an example....from a controller command:
20 | ```
21 | public function index()
22 | {
23 | //add a style sheet
24 | $this->head->style(array('main'));
25 |
26 | //add script files
27 | $this->head->script(array('foojava', 'barjava', 'foobar/java'));
28 |
29 | //change the title
30 | $this->head->title('My title');
31 |
32 | //Pass the head section as the $head variable to the view via a render call
33 | \Flight::render('home/index', array('html_head' => $this->head->head()));
34 | }
35 |
36 | ```
37 |
38 | ####In the view....
39 | ```
40 |
41 |
42 | =$html_head?>
43 |
44 |
45 |
46 | ```
47 |
48 | ####Will produce.....
49 | ```
50 |
51 |
52 |
53 |
54 |
55 |
56 | My title
57 |
58 |
59 | ```
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Directory Browsing Prohibited
8 |
9 |
--------------------------------------------------------------------------------
/docs/input_filtering.md:
--------------------------------------------------------------------------------
1 | #Input Filtering
2 |
3 | The `core\helper\Filter` class includes several static methods that can be useful for filtering data that comes into the application. Many of the filters are just simple implementations of built in methods like `ctype`, but as filtering in web applications is an ever evolving process, using these static wrapper methods, you can adapt your filtering requirements as time goes on by simply updating the static method code rather than endlessly hunt for filtering logic throughout the application.
4 |
5 | The following filters are built into the class:
6 | * filename: by default, accepts alphanumerics plus periods and underscores
7 | * integer
8 | * numeric
9 | * alphanumeric
10 | * alpha
11 | * email (implements the Email type on filter_var)
12 | * boolean
13 | * pageName: by default accepts alphanumeric plus underscore
14 | * databaseField: by default, accepts alphanumerics plus periods and underscores
15 | * checkDateIsValid: this one needs simplification work, I know, but it is functional for now. I am sure there are better ways
16 |
17 | Usage:
18 | `Filter::numeric($data)`
19 |
20 | Returns `true` or `false` depending on if the data is valid.
21 |
22 |
23 |
--------------------------------------------------------------------------------
/docs/logger.md:
--------------------------------------------------------------------------------
1 | #Using the Logger
2 |
3 | The logger is meant to be very simple and intended to implement basic logging functions. The logger class is not loaded by default into the Controller class, and needs to be instantiated.
4 |
5 | ##Configuring
6 | The config object must be passed into the logger.
7 |
8 | The configuration file for each environment contains a `$config['error_log_path']` element which is set to the `error_log/`; directory by default.
9 |
10 | By default, the logger has 4 logging levels:
11 | * event
12 | * notice
13 | * warning
14 | * error
15 |
16 | These levels are setup in the `core/helper/Logger.php` class file in the $foo->levels property of the class. You can modify these logging levels as desired by changing the contents of the array.
17 |
18 | ## Using the logger:
19 | Dynamic methods are used to log events. If you want to log a warning, for example, then you would use the `$foo->warning()` method. The dynamic logger methods accept 2 parameters. The first parameter is the message or description of the log event and the second parameter is any data you want to capture with the log event.
20 |
21 | The logger stores logged events in a text file in the directory that is specified. The name of the file will correspond to the log level like `warning.txt`, `notice.txt`, and so forth.
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/docs/models.md:
--------------------------------------------------------------------------------
1 | #Using Models
2 |
3 | Models are where most of the work should be getting done in your application. This is where the processing takes place and then the results are passed back to the controller and then rendered to a view.
4 |
5 | All models in this extension can pretty well stand on their own and bring in dependencies as needed. The only requirement is adding an appropriate namespace based on the location of the file which at the simplest level will be `application\model`. You can add more subfolders for organization as needed, just be sure to include the appropriate namespace
6 |
7 | You are free to handle your models however you see fit, but the best result will be found in using solid coding practices and observing the concepts of dependency injection, writing testable code, etc. Volumes have been written on these subjects, and you will hopefully find in a study of this extension's code, that every effort was made to develop using these best practices.
--------------------------------------------------------------------------------
/docs/multiple_environments.md:
--------------------------------------------------------------------------------
1 | #Mutliple Environments
2 |
3 | Multiple environments are supported through the use of environment specific configuration files, which are stored in the `/config` directory.
4 |
5 | The environment is determined in 2 ways:
6 | * In the `/config/environment.php` file, you can explicitly set the environment by providing a value for the `APP_ENVIRONMENT` constant
7 | * If you leave the `APP_ENVIRONMENT` constant as a null value, then the auto-detector will take over from and try to determine if you are in a development or testing environment. The `$_SERVER` superglobal array elements `HTTP_HOST, SERVER_NAME, SERVER_ADDRESS, and REMOTE_ADDR` will be searched for a match to anything containing:
8 | * 127.0.0.1
9 | * localhost
10 | * any domain ending in *.dev
11 | * any domain ending in *.local
12 |
13 | If a match is found, the environment will be set to `development`. If no match is found, the environment will be set to testing. The auto detect script will not put the application into the production environment under any circumstances, this must be done manually.
14 |
15 | > The superglobal values and the values that trigger a positive response to go into development mode can be adjusted in the `/core/global_functions.php` file.
16 |
17 | Other custom environments like `staging` can be deployed by adding a `staging.php` file in the `/config` directory, but it will be necessary to explicitly set the environment from the `environment.php` file.
18 |
--------------------------------------------------------------------------------
/docs/views.md:
--------------------------------------------------------------------------------
1 | #Using Views
2 |
3 | Most of the documentation for views can be found by looking at the documentation for Flight at [http://flightphp.com]. The main thing to understand about how this extension implements views is that the views are simply organized into the `application/views` folder. The bootstrapper sets the default view path to this directory.
4 |
5 | I recommend adding a subfolder for each controller to keep things tidy.
6 |
7 | You can call views in a subfolder as follows:
8 |
9 | ```
10 | //let's say we want to render the application/views/home/index.php view file.
11 |
12 | \Flight::render('home/index', array());
13 |
14 | ```
15 |
16 | Layouts work the same way as views as far as directory and file structure are involved. The Flight documentation explains how layouts/templates are implemented.
17 |
--------------------------------------------------------------------------------
/docs/windows_authentication.md:
--------------------------------------------------------------------------------
1 | #Windows Authentication
2 | Flight-MVC has optional Windows authentication built into the router. To enable,
3 | set the configuration variable for using Windows authentication to `true`.
4 |
5 | Note that you will also need to enable Windows Authentication and disable anonymous
6 | authentication in IIS.
7 |
8 | Once you have enabled Windows authentication, you can also enter a domain name (with
9 | a trailing backslash) in the domain config variable to strip the domain name from
10 | the user name if desired.
11 |
12 | To add in more processing when the Windows authentication check takes place, modify
13 | the `core\routes.php` file in the designate area to make it work for you.
--------------------------------------------------------------------------------
/humans.txt:
--------------------------------------------------------------------------------
1 | /* TEAM */
2 | Developer: Andrew Podner
3 | Twitter: @PHPAndy
4 | Location: USA
5 |
6 | /* THANKS */
7 | Flight Micro Framework: http://flightphp.com
8 | Emanuil Rusev: http://erusev.com (Parsedown library)
9 |
10 |
11 | /* SITE */
12 | Last update: 2014/07/15
13 | Software: phpStorm
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 |
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 | NOTE: This license applies only to the code as developed by Andrew Podner. All
24 | other software is licensed as per the license specified by the original developer.
--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------
1 | ## Unit Testing for Flight-MVC
2 |
3 | All of the code for the MVC extension is tested using phpUnit. For the PdoConn class, there is a `unit_test.db` sqlite database in the `/data/sqlite` subfolder. This database is used for some read/write tests. If you find that the tests are failing, make sure that the directory that the database is in is writeable.
4 |
--------------------------------------------------------------------------------
/tests/api_test/delete.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2014
9 | * @license /license.txt
10 | */
11 | if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
12 | echo 'Working';
13 | } else {
14 | echo 'ERROR: not a DELETE Request';
15 | }
--------------------------------------------------------------------------------
/tests/api_test/get.php:
--------------------------------------------------------------------------------
1 | Testing Get Call
--------------------------------------------------------------------------------
/tests/api_test/post-json.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2014
9 | * @license /license.txt
10 | */
11 |
12 | echo file_get_contents("php://input");
--------------------------------------------------------------------------------
/tests/api_test/post-xml.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2014
9 | * @license /license.txt
10 | */
11 | echo file_get_contents("php://input");
--------------------------------------------------------------------------------
/tests/api_test/post.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2014
9 | * @license /license.txt
10 | */
11 |
12 | echo $_POST['b'];
--------------------------------------------------------------------------------
/tests/api_test/put.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2014
9 | * @license /license.txt
10 | */
11 | if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
12 | print_r(getallheaders());
13 | echo file_get_contents("php://input");
14 | } else {
15 | echo 'ERROR: not a PUT Request';
16 | }
17 |
--------------------------------------------------------------------------------
/tests/cli/CliEnvironmentTest.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2013
9 | * @license /license.txt
10 | */
11 |
12 |
13 | class CliEnvironmentTest extends PHPUnit_Framework_TestCase
14 | {
15 | public $config;
16 |
17 | public function setUp()
18 | {
19 | require_once '../cli/lib/Environment.php';
20 | }
21 |
22 | public function tearDown() {}
23 |
24 | /**
25 | * @expectedException Exception
26 | */
27 | public function testNullConstructor() {
28 | $test = new \fmvc\cli\lib\Environment();
29 | }
30 |
31 | /**
32 | * @expectedException Exception
33 | */
34 | public function testNullConstructor2() {
35 | $test = new \fmvc\cli\lib\Environment('test');
36 | }
37 |
38 | public function testConstructor()
39 | {
40 | $test = new \fmvc\cli\lib\Environment('test', 'file.php');
41 | $this->assertEquals('test', $test->mode);
42 | $this->assertEquals('file.php', $test->fileName);
43 | }
44 |
45 | public function testWriteFile()
46 | {
47 | $file = 'temp/testwrite.txt';
48 | if (file_exists($file)) {
49 | unlink($file);
50 | }
51 | $env = new \fmvc\cli\lib\Environment('test', $file);
52 |
53 | file_put_contents($file, 'Test data');
54 | $this->assertTrue($env->writeFile('my test data'));
55 |
56 | $newData = file_get_contents($file);
57 | $this->assertEquals('my test data', $newData);
58 | unlink($file);
59 | }
60 |
61 | public function testWriteFileFail()
62 | {
63 | $file = 'temp/testwrite.txt';
64 | if (file_exists($file)) {
65 | unlink($file);
66 | }
67 | file_put_contents($file, 'Test data');
68 | $env = new \fmvc\cli\lib\Environment('test', $file);
69 | $this->assertFalse($env->writeFile(''));
70 | }
71 |
72 | public function testHalt()
73 | {
74 | $file = 'temp/testwrite.txt';
75 | if (file_exists($file)) {
76 | unlink($file);
77 | }
78 | file_put_contents($file, 'Test data');
79 | $env = new \fmvc\cli\lib\Environment('halt', $file);
80 | $this->assertTrue($env->toggleHalt());
81 |
82 | $data = file_get_contents($file);
83 | $this->assertStringStartsWith("assertFalse($env->toggleHalt());
95 | }
96 | public function testStart()
97 | {
98 | $file = 'temp/testwrite.txt';
99 | if (file_exists($file)) {
100 | unlink($file);
101 | }
102 | file_put_contents($file, 'Test data');
103 | $env = new \fmvc\cli\lib\Environment('start', $file);
104 | $this->assertTrue($env->toggleHalt());
105 |
106 | $data = file_get_contents($file);
107 | $this->assertEquals("assertTrue($env->toggleEnvironment());
120 |
121 | $data = file_get_contents($file);
122 | $this->assertEquals("define('APP_ENVIRONMENT', 'development');\r\n", $data);
123 | unlink($file);
124 | }
125 |
126 | public function testToggleEnvironmentFail()
127 | {
128 | $file = 'temp/testwrite.txt';
129 | if (file_exists($file)) {
130 | unlink($file);
131 | }
132 | $env = new \fmvc\cli\lib\Environment('start', $file);
133 | $this->assertFalse($env->toggleEnvironment());
134 | }
135 |
136 | public function testAutoDetect()
137 | {
138 | $file = 'temp/testwrite.txt';
139 | if (file_exists($file)) {
140 | unlink($file);
141 | }
142 | file_put_contents($file, '');
143 | $env = new \fmvc\cli\lib\Environment('auto', $file);
144 | $this->assertTrue($env->toggleEnvironment());
145 |
146 | $data = file_get_contents($file);
147 | $this->assertEquals("define('APP_ENVIRONMENT', null);\r\n", $data);
148 | unlink($file);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/tests/cli/CliFilegenTest.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2013
9 | * @license /license.txt
10 | */
11 | class CliFilegenTest extends PHPUnit_Framework_TestCase
12 | {
13 |
14 | public function setUp()
15 | {
16 | require_once '../cli/lib/Filegen.php';
17 | }
18 |
19 | public function tearDown()
20 | {
21 | if (file_exists('temp/test.php')) unlink('temp/test.php');
22 | if (file_exists('temp/my')) rmdir('temp/my');
23 | }
24 |
25 | public function testCreateObject()
26 | {
27 | $fgen = new \fmvc\cli\lib\Filegen();
28 | $result = $fgen->createObject('controller', 'test', 'temp/', '../cli/templates/');
29 | $text = file_get_contents('temp/Test.php');
30 | $test = (stristr($text, 'class Test extends \fmvc\core\lib\Controller') !== false) ? true : false;
31 | $this->assertFileExists('temp/Test.php');
32 | unlink('temp/Test.php');
33 | $this->assertTrue($test);
34 | }
35 |
36 | public function testCreateObjectWithSubdir()
37 | {
38 | $fgen = new \fmvc\cli\lib\Filegen();
39 | $result = $fgen->createObject('controller', 'my/test', 'temp/', '../cli/templates/');
40 | $text = file_get_contents('temp/my/Test.php');
41 | $test = (stristr($text, 'class Test extends \fmvc\core\lib\Controller') !== false) ? true : false;
42 | $this->assertFileExists('temp/my/Test.php');
43 | unlink('temp/my/Test.php');
44 | rmdir('temp/my');
45 | $this->assertTrue($test);
46 | }
47 |
48 | public function testCreateView()
49 | {
50 | $fgen = new \fmvc\cli\lib\Filegen();
51 | $result = $fgen->createObject('view', 'test', 'temp/', '../cli/templates/');
52 | $text = file_get_contents('temp/test.php');
53 | $test = (stristr($text, '') !== false) ? true : false;
54 | $this->assertFileExists('temp/test.php');
55 | unlink('temp/test.php');
56 | $this->assertTrue($test);
57 | }
58 |
59 | /**
60 | * @expectedException Exception
61 | */
62 | public function testCreateObjectFailAlreadyExists()
63 | {
64 | file_put_contents('temp/test.php', 'test 123');
65 | $fgen = new \fmvc\cli\lib\Filegen();
66 | $result = $fgen->createObject('view', 'test', 'temp/', '../cli/templates/');
67 | }
68 |
69 | /**
70 | * @expectedException Exception
71 | */
72 | public function testCreateWriteFileFailure()
73 | {
74 | mkdir('temp/my');
75 | chmod('temp/my', 0000);
76 | $fgen = new \fmvc\cli\lib\Filegen();
77 | $result = $fgen->createFile('temp/my', null, null);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/tests/core/ConfigTest.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2013
9 | * @license /license.txt
10 | */
11 | class ConfigTest extends PHPUnit_Framework_TestCase
12 | {
13 | public $config;
14 |
15 | public function setUp()
16 | {
17 | require_once '../core/lib/Config.php';
18 | $configTest = array(0 => 'apples',
19 | 1 => 'pears',
20 | 2 => 'bananas');
21 | $this->config = new \fmvc\core\lib\Config($configTest);
22 | }
23 |
24 | public function tearDown() {}
25 |
26 | /**
27 | * @expectedException Exception
28 | */
29 | public function testNullConstructor() {
30 | $test = new \fmvc\core\lib\Config();
31 | }
32 |
33 | public function testConstructor()
34 | {
35 | $cfg = $this->config->c_config;
36 | $this->assertEquals('apples', $cfg[0]);
37 | $this->assertEquals(3, count($cfg));
38 | }
39 |
40 | public function testItem()
41 | {
42 | $this->assertEquals('apples', $this->config->item(0));
43 | $this->assertEquals(3, count($this->config->item()));
44 | }
45 |
46 | public function testSetItem()
47 | {
48 | $this->config->set('value', 'testValue');
49 | $this->assertEquals('testValue', $this->config->item('value'));
50 | }
51 |
52 | /**
53 | * @expectedException Exception
54 | */
55 | public function testSetNull() {
56 | $this->config->set('item');
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/core/ControllerTest.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2013
9 | * @license /license.txt
10 | */
11 | require_once '../core/lib/Controller.php';
12 | require_once '../core/lib/Input.php';
13 |
14 | use \fmvc\core\lib\Input;
15 |
16 | if (! session_id()) {
17 | session_start();
18 | }
19 |
20 | class ControllerTest extends PHPUnit_Framework_TestCase
21 |
22 | {
23 | public $input;
24 |
25 | public function setUp()
26 | {
27 |
28 | }
29 |
30 | public function tearDown()
31 | {
32 |
33 | }
34 |
35 | public function testConstructorDocRoot()
36 | {
37 | $stub = $this->getMockBuilder('config')
38 | ->getMock();
39 | $input = new Input(array('config'=>$stub));
40 | $arrParams = array('param1', 'param2');
41 | $ctrl = new \fmvc\core\lib\Controller(array('config' => $stub, 'input' => $input), $arrParams);
42 | }
43 |
44 | public function testConstructorHttpHost()
45 | {
46 | $stub = $this->getMockBuilder('config')
47 | ->getMock();
48 | $input = new Input(array('config'=>$stub));
49 | $input->server['HTTP_HOST'] = 'example.com';
50 | $arrParams = array('param1', 'param2');
51 | $ctrl = new \fmvc\core\lib\Controller(array('config' => $stub, 'input' => $input), $arrParams);
52 | }
53 |
54 | /**
55 | * @expectedException \Exception
56 | */
57 | public function testConstructorNull()
58 | {
59 | $fail = new \fmvc\core\lib\Controller();
60 | }
61 |
62 |
63 |
64 | }
--------------------------------------------------------------------------------
/tests/core/DocumentationTest.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright 2013
9 | * @license /license.txt
10 | */
11 | require_once '../core/helper/Documentation.php';
12 |
13 | use fmvc\core\helper\Documentation;
14 |
15 | class DocumentationTest extends PHPUnit_Framework_TestCase
16 | {
17 |
18 |
19 | /**
20 | * Mock of the Parsedown Object
21 | * @var
22 | */
23 | public $parse;
24 |
25 |
26 | public function setUp()
27 | {
28 | $this->parse = $this->getMockBuilder('Parsedown')
29 | ->disableOriginalConstructor()
30 | ->setMethods(array('text'))
31 | ->getMock();
32 |
33 |
34 | }
35 |
36 | public function tearDown()
37 | {
38 |
39 | }
40 |
41 | public function testConstructor()
42 | {
43 | $doc = new Documentation('testVal');
44 | $this->assertEquals('testVal', $doc->dirName);
45 | }
46 |
47 | public function testConstructorNull()
48 | {
49 | $doc = new Documentation();
50 | $this->assertEquals('./docs', $doc->dirName);
51 | }
52 |
53 | public function testGetDocumentationFilenames()
54 | {
55 | $doc = new Documentation('../docs');
56 | $array = $doc->getDocumentationFileNames();
57 | $this->assertArrayHasKey(1,$array);
58 | }
59 |
60 | public function testParseDocumentationFile()
61 | {
62 | $doc = new Documentation('../temp');
63 |
64 | $this->parse->expects($this->once())
65 | ->method('text')
66 | ->will($this->returnValue('