Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit 2e7a91b7771fb083a0269e134f62f274f85685c7 0 parents
@juzna authored
1  .gitignore
@@ -0,0 +1 @@
+temp/cache
58 app/bootstrap.php
@@ -0,0 +1,58 @@
+<?php
+
+use Nette\Debug,
+ Nette\Environment,
+ Nette\Application\Route,
+ Nette\Application\SimpleRouter;
+
+
+
+// Step 1: Load Nette Framework
+// this allows load Nette Framework classes automatically so that
+// you don't have to litter your code with 'require' statements
+require LIBS_DIR . '/Nette/loader.php';
+
+
+
+// Step 2: Configure environment
+// 2a) enable Nette\Debug for better exception and error visualisation
+Debug::enable();
+
+// 2b) load configuration from config.ini file
+Environment::loadConfig();
+
+
+
+// Step 3: Configure application
+// 3a) get and setup a front controller
+$application = Environment::getApplication();
+
+// 3b) establish database connection
+$application->onStartup[] = 'Albums::initialize';
+
+
+
+// Step 4: Setup application router
+$router = $application->getRouter();
+
+// mod_rewrite detection
+if (false && function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) {
+ $router[] = new Route('index.php', array(
+ 'presenter' => 'Dashboard',
+ 'action' => 'default',
+ ), Route::ONE_WAY);
+
+ $router[] = new Route('<presenter>/<action>/<id>', array(
+ 'presenter' => 'Dashboard',
+ 'action' => 'default',
+ 'id' => NULL,
+ ));
+
+} else {
+ $router[] = new SimpleRouter('Dashboard:default');
+}
+
+
+
+// Step 5: Run the application!
+$application->run();
22 app/config.ini
@@ -0,0 +1,22 @@
+;
+; SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser!
+; http://nette.org/security-warning
+;
+[common]
+; PHP configuration
+php.date.timezone = "Europe/Prague"
+
+; services
+service.Nette-Loaders-RobotLoader.option.directory[] = %appDir%
+service.Nette-Loaders-RobotLoader.option.directory[] = %libsDir%
+service.Nette-Loaders-RobotLoader.run = TRUE
+
+[production < common]
+; common database connection
+database.driver = sqlite
+database.file = "%appDir%/models/demo.db"
+database.lazy = TRUE
+
+[development < production]
+; database options in development mode
+database.profiler = TRUE
66 app/models/Albums.php
@@ -0,0 +1,66 @@
+<?php
+
+use Nette\Object,
+ Nette\Environment;
+
+
+/**
+ * Albums model.
+ */
+class Albums extends Object
+{
+ /** @var string */
+ private $table = 'albums';
+
+ /** @var DibiConnection */
+ private $connection;
+
+
+ public static function initialize()
+ {
+ dibi::connect(Environment::getConfig('database'));
+ }
+
+
+
+ public function __construct()
+ {
+ $this->connection = dibi::getConnection();
+ }
+
+
+
+ public function findAll()
+ {
+ return $this->connection->select('*')->from($this->table);
+ }
+
+
+
+ public function find($id)
+ {
+ return $this->connection->select('*')->from($this->table)->where('id=%i', $id);
+ }
+
+
+
+ public function update($id, array $data)
+ {
+ return $this->connection->update($this->table, $data)->where('id=%i', $id)->execute();
+ }
+
+
+
+ public function insert(array $data)
+ {
+ return $this->connection->insert($this->table, $data)->execute(dibi::IDENTIFIER);
+ }
+
+
+
+ public function delete($id)
+ {
+ return $this->connection->delete($this->table)->where('id=%i', $id)->execute();
+ }
+
+}
68 app/models/UsersModel.php
@@ -0,0 +1,68 @@
+<?php
+
+use Nette\Object,
+ Nette\Security\AuthenticationException;
+
+
+/**
+ * Users authenticator.
+ */
+class UsersModel extends Object implements Nette\Security\IAuthenticator
+{
+ const MODE_PASS = 1;
+ const MODE_OPENID = 2;
+
+ /**
+ * Performs an authentication
+ * @param array
+ * @return IIdentity
+ * @throws AuthenticationException
+ */
+ public function authenticate(array $credentials)
+ {
+ switch($credentials[0]) {
+ case self::MODE_PASS: return $this->authenticateByPassword($credentials[1], $credentials[2]);
+ case self::MODE_OPENID: return $this->authenticateByOpenId($credentials[1]);
+ default: throw new AuthenticationException("Invalid authentication mode");
+ }
+ }
+
+ private function authenticateByPassword($username, $password) {
+ $row = dibi::select('*')->from('users')->where('username=%s', $username)->fetch();
+
+ if (!$row) {
+ throw new AuthenticationException("User '$username' not found.", self::IDENTITY_NOT_FOUND);
+ }
+
+ if ($row->password !== $this->calculateHash($password)) {
+ throw new AuthenticationException("Invalid password.", self::INVALID_CREDENTIAL);
+ }
+
+ unset($row->password);
+ return new Nette\Security\Identity($row->id, NULL, $row);
+ }
+
+ /**
+ * Computes salted password hash.
+ * @param string
+ * @return string
+ */
+ public function calculateHash($password)
+ {
+ return md5($password . str_repeat('*random salt*', 10));
+ }
+
+ /**
+ * Authenticate via OpenID URI
+ */
+ private function authenticateByOpenId($uri) {
+ $row = dibi::select('*')->from('openid')->where('openid=%s', $uri)->fetch();
+ if(!$row) throw new AuthenticationException("Unknown OpenID");
+
+ // Find user
+ $user = dibi::select('*')->from('users')->where('id=%i', $row->userid)->fetch();
+
+ unset($user->password);
+ return new Nette\Security\Identity($user->id, NULL, $user);
+ }
+}
BIN  app/models/demo.db
Binary file not shown
8 app/presenters/BasePresenter.php
@@ -0,0 +1,8 @@
+<?php
+
+use Nette\Application\Presenter;
+
+
+abstract class BasePresenter extends Presenter
+{
+}
138 app/presenters/DashboardPresenter.php
@@ -0,0 +1,138 @@
+<?php
+
+use Nette\Application\AppForm,
+ Nette\Forms\Form;
+
+
+
+class DashboardPresenter extends BasePresenter
+{
+
+
+ /********************* view default *********************/
+
+
+
+ public function renderDefault()
+ {
+ $album = new Albums;
+ $this->template->albums = $album->findAll()->orderBy('artist')->orderBy('title');
+ }
+
+
+
+ /********************* views add & edit *********************/
+
+
+
+ public function renderAdd()
+ {
+ $this['albumForm']['save']->caption = 'Add';
+ }
+
+
+
+ public function renderEdit($id = 0)
+ {
+ $form = $this['albumForm'];
+ if (!$form->isSubmitted()) {
+ $album = new Albums;
+ $row = $album->find($id)->fetch();
+ if (!$row) {
+ throw new Nette\Application\BadRequestException('Record not found');
+ }
+ $form->setDefaults($row);
+ }
+ }
+
+
+
+ /********************* view delete *********************/
+
+
+
+ public function renderDelete($id = 0)
+ {
+ $album = new Albums;
+ $this->template->album = $album->find($id)->fetch();
+ if (!$this->template->album) {
+ throw new Nette\Application\BadRequestException('Record not found');
+ }
+ }
+
+
+
+ /********************* component factories *********************/
+
+
+
+ /**
+ * Album edit form component factory.
+ * @return mixed
+ */
+ protected function createComponentAlbumForm()
+ {
+ $form = new AppForm;
+ $form->addText('artist', 'Artist:')
+ ->addRule(Form::FILLED, 'Please enter an artist.');
+
+ $form->addText('title', 'Title:')
+ ->addRule(Form::FILLED, 'Please enter a title.');
+
+ $form->addSubmit('save', 'Save')->setAttribute('class', 'default');
+ $form->addSubmit('cancel', 'Cancel')->setValidationScope(NULL);
+ $form->onSubmit[] = callback($this, 'albumFormSubmitted');
+
+ $form->addProtection('Please submit this form again (security token has expired).');
+ return $form;
+ }
+
+
+
+ public function albumFormSubmitted(AppForm $form)
+ {
+ if ($form['save']->isSubmittedBy()) {
+ $id = (int) $this->getParam('id');
+ $album = new Albums;
+ if ($id > 0) {
+ $album->update($id, $form->values);
+ $this->flashMessage('The album has been updated.');
+ } else {
+ $album->insert($form->values);
+ $this->flashMessage('The album has been added.');
+ }
+ }
+
+ $this->redirect('default');
+ }
+
+
+
+ /**
+ * Album delete form component factory.
+ * @return mixed
+ */
+ protected function createComponentDeleteForm()
+ {
+ $form = new AppForm;
+ $form->addSubmit('cancel', 'Cancel');
+ $form->addSubmit('delete', 'Delete')->setAttribute('class', 'default');
+ $form->onSubmit[] = callback($this, 'deleteFormSubmitted');
+ $form->addProtection('Please submit this form again (security token has expired).');
+ return $form;
+ }
+
+
+
+ public function deleteFormSubmitted(AppForm $form)
+ {
+ if ($form['delete']->isSubmittedBy()) {
+ $album = new Albums;
+ $album->delete($this->getParam('id'));
+ $this->flashMessage('Album has been deleted.');
+ }
+
+ $this->redirect('default');
+ }
+
+}
35 app/templates/@layout.phtml
@@ -0,0 +1,35 @@
+{**
+ * Layout of Nette Framework example CD collection (Akrabat)
+ *
+ * @package MyApplication
+ *
+ * @param string $robots tell robots how to index the content of a page (optinal)
+ * @param string $basePath web base path
+ * @param array $flashes flash messages
+ * @param Nette\Web\User $user current user
+ *}
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Language" content="en" />
+
+ <meta name="description" content="Nette Framework example" />
+ <meta n:ifset="$robots" name="robots" content="{$robots}">
+
+ <title>{block #title|striptags|trim}{/block} | Nette example</title>
+
+ <link rel="stylesheet" type="text/css" media="screen" href="{$basePath}/css/site.css" />
+</head>
+
+<body>
+ <div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
+
+ <div id="content">
+ {include #content}
+ </div>
+
+ <p id="logged-in" n:if="$user->loggedIn">Signed in as {$user->identity->username} ({$user->identity->real_name}). <a href="{link Sign:out}">Sign out</a></p>
+</body>
+</html>
5 app/templates/Dashboard/add.phtml
@@ -0,0 +1,5 @@
+{block #content}
+
+<h1 n:block="title">Add New Album</h1>
+
+{control albumForm}
24 app/templates/Dashboard/default.phtml
@@ -0,0 +1,24 @@
+{block #content}
+
+<h1 n:block="title">My Albums</h1>
+
+<p><a href="{link add}">Add new album</a></p>
+
+<table class="grid">
+<tr>
+ <th>Title</th>
+ <th>Artist</th>
+ <th>&nbsp;</th>
+</tr>
+
+{foreach $albums as $album}
+<tr>
+ <td>{$album->title}</td>
+ <td>{$album->artist}</td>
+ <td>
+ <a href="{link edit, $album->id}">Edit</a>
+ <a href="{link delete, $album->id}">Delete</a>
+ </td>
+</tr>
+{/foreach}
+</table>
11 app/templates/Dashboard/delete.phtml
@@ -0,0 +1,11 @@
+{block #content}
+
+<h1 n:block="title">Delete Album</h1>
+
+{if $album}
+ <p>Are you sure that you want to delete ‘{$album->title}’ by ‘{$album->artist}’?</p>
+ {control deleteForm}
+
+{else}
+ <p>Cannot find album.</p>
+{/if}
5 app/templates/Dashboard/edit.phtml
@@ -0,0 +1,5 @@
+{block #content}
+
+<h1 n:block="title">Edit Album</h1>
+
+{control albumForm}
13 document_root/.htaccess
@@ -0,0 +1,13 @@
+# disable directory listing
+Options -Indexes
+
+# mod_rewrite
+<IfModule mod_rewrite.c>
+ RewriteEngine On
+ # RewriteBase /
+
+ # front controller
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz)$ index.php [L]
+</IfModule>
108 document_root/css/site.css
@@ -0,0 +1,108 @@
+body {
+ font: 16px/1.5 "Trebuchet MS", "Geneva CE", lucida, sans-serif;
+ color: #333;
+ background-color: #fff;
+ margin: 2em;
+}
+
+h1 {
+ font-size: 1.9em;
+ color: #3484D2;
+}
+
+h2 {
+ font-size: 1.2em;
+ color: #3484D2;
+}
+
+#content {
+ width: 770px;
+ margin: 0 5px;
+}
+
+a {
+ color: #000080;
+}
+
+#logged-in {
+ margin-top: 3em;
+ font-size: 90%;
+}
+
+div.flash {
+ color: black;
+ background: #FFFFDD;
+ border: 1px solid #FFD700;
+ padding: 1em;
+ margin: 1em 0;
+}
+
+
+
+/*------------------------------------------------------------------*/
+
+
+table.grid {
+ padding: 0;
+ margin: 0;
+ border-collapse:collapse;
+}
+
+table.grid td, table.grid th {
+ background: #fff;
+ border: 1px solid #add4fb;
+ padding: 6px 6px 6px 12px;
+}
+
+table.grid th {
+ color: #7a7772;
+ background: #E4F1FC;
+ text-align: left;
+ font-weight: normal;
+ font-size: 80%;
+}
+
+table.grid .alt td {
+ background: #f8f8f0;
+}
+
+
+
+/*------------------------------------------------------------------*/
+
+
+
+form {
+ max-width: 500px;
+ padding: .8em 1.6em;
+ background: #E4F1FC;
+ border: solid 2px #add4fb;
+}
+
+form input {
+ margin: 2px 0;
+ font-size: 100%;
+}
+
+form input.default {
+ font-weight: bold;
+ font-size: 105%;
+}
+
+form input.text {
+ padding: 4px 2px;
+ border: solid 1px #add4fb;
+ min-width: 200px;
+}
+
+form label {
+ width: 100px;
+ display: block;
+ text-align: right;
+ margin-right: 5px;
+ font-weight: normal;
+}
+
+form .required label {
+ font-weight: bold;
+}
16 document_root/index.php
@@ -0,0 +1,16 @@
+<?php
+
+// absolute filesystem path to the web root
+define('WWW_DIR', __DIR__);
+
+// absolute filesystem path to the application root
+define('APP_DIR', WWW_DIR . '/../app');
+
+// absolute filesystem path to the libraries
+define('LIBS_DIR', WWW_DIR . '/../libs');
+
+// absolute filesystem path to the temporary files
+define('TEMP_DIR', WWW_DIR . '/../temp');
+
+// load bootstrap file
+require APP_DIR . '/bootstrap.php';
2  log/.htaccess
@@ -0,0 +1,2 @@
+Order Allow,Deny
+Deny from all
2  temp/.htaccess
@@ -0,0 +1,2 @@
+Order Allow,Deny
+Deny from all
Please sign in to comment.
Something went wrong with that request. Please try again.