Skip to content

Commit 06d0c6b

Browse files
committed
Initial commit
1 parent 0b6fa8c commit 06d0c6b

File tree

117 files changed

+5293
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+5293
-0
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
php-survey-builder
2+
3+
*php-survey-builder* is a PHP web application that lets you create surveys and collect survey responses. The results can be viewed on charts and exported to CSV. The survey data is stored within a sqlite3 database.
4+
5+
![screenshot of php-survey-builder](https://raw.github.com/phpdave11/php-survey-builder/master/screenshots/survey_edit.png)
6+
7+
## Default login
8+
9+
The default login is 'root@localhost' with a password of '12345'. You can add and remove logins from the Users tab.
10+
11+
## Troubleshooting
12+
13+
Be sure that your data/ directory is writable by your web server.

config/Database.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dsn = "sqlite:data/database.sqlite3"
2+
filename = "data/database.sqlite3"
3+

controllers/Controller.php

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
<?php
2+
3+
// Set include path to look for classes in the models directory, then in the controllers directory
4+
set_include_path(get_include_path() . PATH_SEPARATOR . 'models' . PATH_SEPARATOR . 'controllers');
5+
6+
// Register the autoload function to automatically include classes
7+
spl_autoload_register(array('Controller', 'autoload'));
8+
9+
/**
10+
* The Controller class is an abstract class used to handle user requests and make use of various
11+
* models and views
12+
*
13+
* @author David Barnes
14+
* @copyright Copyright (c) 2013, David Barnes
15+
*/
16+
abstract class Controller
17+
{
18+
const DSN_CONFIG_FILE = 'config/Database.ini';
19+
const DATABASE_SCHEMA_FILE = 'data/schema.sql';
20+
const INITIAL_DATA_FILE = 'data/initial_data.sql';
21+
const SESSION_NAME = 'SURVEYFORMAPP';
22+
const RUNTIME_EXCEPTION_VIEW = 'runtime_exception.php';
23+
24+
protected $config;
25+
protected $dsn;
26+
protected $pdo;
27+
protected $viewVariables = array();
28+
29+
/**
30+
* Get the filename of the view file containing HTML and PHP presentation logic
31+
*
32+
* @return string returns the view filename
33+
*/
34+
protected function getViewFilename()
35+
{
36+
return basename($_SERVER['SCRIPT_NAME']);
37+
}
38+
39+
/**
40+
* Handle the page request
41+
*
42+
* @param array $request the page parameters from a form post or query string
43+
*/
44+
abstract protected function handleRequest(&$request);
45+
46+
/**
47+
* Handle an exception and display the error to the user
48+
*
49+
* @param Exception $e the Exception to be displayed
50+
*/
51+
protected function handleError(Exception $e)
52+
{
53+
$this->assign('statusMessage', $e->getMessage());
54+
}
55+
56+
/**
57+
* Assign a variable to be used in the view
58+
*
59+
* @param string $name the variable name
60+
* @param mixed $value the variable value
61+
*/
62+
protected function assign($name, $value)
63+
{
64+
$this->viewVariables[$name] = $value;
65+
}
66+
67+
/**
68+
* Display the view associated with the controller
69+
*/
70+
protected function displayView($viewFilename)
71+
{
72+
chdir('views');
73+
74+
if (! file_exists($viewFilename))
75+
throw new RuntimeException("Filename does not exist: $viewFilename");
76+
77+
// Extract view variables into current scope
78+
extract($this->viewVariables);
79+
80+
// Display the view
81+
require $viewFilename;
82+
}
83+
84+
/**
85+
* Automatically load the necessary file for a given class
86+
*
87+
* @param string $class the class name to autoload
88+
*/
89+
public static function autoload($class)
90+
{
91+
require $class . '.php';
92+
return true;
93+
}
94+
95+
/**
96+
* Display the page - open the database, execute controller code, and display the view
97+
*/
98+
public function display()
99+
{
100+
// Make sure requests and responses are utf-8
101+
header('Content-type: text/html; charset=utf-8');
102+
103+
try
104+
{
105+
// Check to make sure required dependencies are installed
106+
$this->checkDependencies();
107+
108+
// Open PDO database connection
109+
$this->openDatabase();
110+
111+
// Handle the page request
112+
$this->handleRequest($_REQUEST);
113+
114+
// Get view filename
115+
$viewFilename = $this->getViewFilename();
116+
117+
// Display the view
118+
$this->displayView($viewFilename);
119+
}
120+
catch (RuntimeException $e)
121+
{
122+
$this->assign('statusMessage', $e->getMessage());
123+
$this->displayView(self::RUNTIME_EXCEPTION_VIEW);
124+
}
125+
catch (Exception $e)
126+
{
127+
// Handle exception
128+
$this->handleError($e);
129+
130+
// Get view filename
131+
$viewFilename = $this->getViewFilename();
132+
133+
// Display view
134+
if ($viewFilename)
135+
$this->displayView($viewFilename);
136+
else
137+
die($e->getMessage());
138+
}
139+
}
140+
141+
/**
142+
* Start a new session with the session name defined in the
143+
* SESSION_NAME class constant
144+
*/
145+
protected function startSession()
146+
{
147+
session_name(self::SESSION_NAME);
148+
149+
session_start();
150+
}
151+
152+
/**
153+
* Get the current user sessions, or redirect to the login page
154+
*/
155+
protected function getUserSession()
156+
{
157+
$this->startSession();
158+
159+
if (!isset($_SESSION['login']))
160+
$this->redirect('login.php');
161+
162+
return $_SESSION['login'];
163+
}
164+
165+
/**
166+
* Redirect to another URL
167+
*
168+
* @param string $url the URL to redirect to
169+
*/
170+
protected function redirect($url)
171+
{
172+
// Close session information
173+
if (session_id() != "")
174+
session_write_close();
175+
176+
header("Location: $url");
177+
exit;
178+
}
179+
180+
/**
181+
* Check for required dependencies and throw an exception if not all dependencies are found
182+
*
183+
* @throws RuntimeException if a required dependency is not found
184+
*/
185+
protected function checkDependencies()
186+
{
187+
$missing = array();
188+
189+
if (! extension_loaded('openssl'))
190+
$missing[] = 'openssl';
191+
192+
if (! extension_loaded('pdo'))
193+
$missing[] = 'PDO';
194+
195+
// Version 3.6.19 is required for foreign key support and cascade support
196+
if (! extension_loaded('sqlite3'))
197+
$missing[] = 'sqlite3 version 3.6.19 or higher';
198+
else
199+
{
200+
$versionArray = sqlite3::version();
201+
$versionString = $versionArray['versionString'];
202+
if (version_compare($versionString, '3.6.19', '<'))
203+
$missing[] = 'sqlite3 version 3.6.19 or higher';
204+
}
205+
206+
if (! extension_loaded('pdo_sqlite'))
207+
$missing[] = 'pdo_sqlite';
208+
209+
if (!empty($missing))
210+
throw new RuntimeException("The following PHP extensions are required:\n\n" . implode("\n", $missing));
211+
}
212+
213+
/**
214+
* Open a PDO connection to the database and assign it to instance variable $pdo
215+
*
216+
* @throws RuntimeException if the database could not be opened
217+
*/
218+
protected function openDatabase()
219+
{
220+
if (! file_exists(self::DSN_CONFIG_FILE))
221+
throw new RuntimeException('Database config file not found: ' . self::DSN_CONFIG_FILE);
222+
223+
$databaseConfig = parse_ini_file(self::DSN_CONFIG_FILE);
224+
if (!isset($databaseConfig['dsn']))
225+
throw new RuntimeException("Database config parameter 'dsn' not found in config file: " . self::DSN_CONFIG_FILE);
226+
227+
if (!isset($databaseConfig['filename']))
228+
throw new RuntimeException("Database config parameter 'filename' not found in config file: " . self::DSN_CONFIG_FILE);
229+
230+
if (!is_writable(dirname($databaseConfig['filename'])))
231+
throw new RuntimeException('Data directory not writable by web server: ' . dirname($databaseConfig['filename']) . '/');
232+
233+
if (!is_writable(dirname($databaseConfig['filename'])) || (file_exists($databaseConfig['filename']) && !is_writable($databaseConfig['filename'])))
234+
throw new RuntimeException('Database file not writable by web server: ' . $databaseConfig['filename']);
235+
236+
try
237+
{
238+
$this->pdo = new PDO($databaseConfig['dsn']);
239+
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
240+
$this->pdo->exec('PRAGMA foreign_keys = ON;');
241+
242+
if (! $this->databaseTablesCreated())
243+
$this->createDatabaseTables();
244+
}
245+
catch (PDOException $e)
246+
{
247+
throw new RuntimeException('PDOException: ' . $e->getMessage());
248+
}
249+
}
250+
251+
/**
252+
* Create database tables from SQL schema file
253+
*/
254+
protected function createDatabaseTables()
255+
{
256+
if (! file_exists(self::DATABASE_SCHEMA_FILE))
257+
throw new RuntimeException("Database schema file not found: " . self::DATABASE_SCHEMA_FILE);
258+
259+
// Create tables
260+
$sql = file_get_contents(self::DATABASE_SCHEMA_FILE);
261+
$this->pdo->exec($sql);
262+
263+
// Load initial data
264+
$sql = file_get_contents(self::INITIAL_DATA_FILE);
265+
$this->pdo->exec($sql);
266+
}
267+
268+
/**
269+
* Determine if database tables have already been created
270+
*/
271+
protected function databaseTablesCreated()
272+
{
273+
$sql = "select count(*) from sqlite_master where type='table' and name='login'";
274+
$stmt = $this->pdo->prepare($sql);
275+
$stmt->execute();
276+
$stmt->setFetchMode(PDO::FETCH_NUM);
277+
if ($row = $stmt->fetch())
278+
{
279+
if ($row[0] == 1)
280+
return true;
281+
}
282+
return false;
283+
}
284+
}
285+
286+
?>

controllers/IndexController.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/**
4+
* The IndexController class is a Controller that shows the home page
5+
*
6+
* @author David Barnes
7+
* @copyright Copyright (c) 2013, David Barnes
8+
*/
9+
class IndexController extends Controller
10+
{
11+
/**
12+
* Handle the page request
13+
*
14+
* @param array $request the page parameters from a form post or query string
15+
*/
16+
protected function handleRequest(&$request)
17+
{
18+
$user = $this->getUserSession();
19+
$this->assign('user', $user);
20+
}
21+
}
22+
23+
?>

0 commit comments

Comments
 (0)