diff --git a/include/class-App.php b/include/class-App.php index f781c17..4a0ec8e 100644 --- a/include/class-App.php +++ b/include/class-App.php @@ -1,66 +1,66 @@ . /** * Methods of an App class */ trait AppTrait { /** * Get the App ID * * @return int */ public function getAppID() { return $this->get( 'app_ID' ); } /** * Get the App name * * @return string */ public function getAppName() { return $this->get( 'app_name' ); } /** * Normalize an App after being retrieved from database */ protected function normalizeApp() { $this->integers( 'app_ID' ); } } /** * Class that can wrap an App retrieved from the database * * An App rappresents an instance of a WikiCAPTCHA application * assigned to a website. */ -class App { +class App extends Queried { use AppTrait; /** * Constructor */ public function __construct() { $this->normalizeApp(); } } diff --git a/include/class-Page.php b/include/class-Page.php index 789a473..2e010fd 100644 --- a/include/class-Page.php +++ b/include/class-Page.php @@ -1,87 +1,104 @@ . /** * A website page * * It's useful to print the header, the footer, and who knows */ class Page { /** * Custom arguments * * @var array */ protected $args; /** * Constructor * * @param array $args Custom arguments */ public function __construct( $args = [] ) { $this->args = $args; + // is there a known page UID? + if( isset( $args['uid'] ) ) { + + // check if we know this page + $page = menu_entry( $args['uid'] ); + if( $page ) { + + // check if I'm allowed to see this page + if( !$page->isVisible() ) { + require_more_privileges(); + } + + // set a default page title + $this->setTitle( $page->name ); + } + } + $this->prepare(); } /** * Set a page argument * * @param $name string * @param $value mixed * @return self */ protected function setArg( $name, $value ) { $this->args[ $name ] = $value; return $this; } /** * Set the page title * * @param $title string * @return self */ protected function setTitle( $title ) { return $this->setArg( 'title', $title ); } /** * Do something at startup */ protected function prepare() { // actually nothing. You can override this! } /** * Print the site header */ public function printHeader() { template( 'header', $this->args ); } /** * Print the site footer */ public function printFooter() { template( 'footer', $this->args ); } } diff --git a/include/class-PageApp.php b/include/class-PageApp.php new file mode 100644 index 0000000..13ffc7a --- /dev/null +++ b/include/class-PageApp.php @@ -0,0 +1,158 @@ +. + +/** + * Page for editing a single App + */ +class PageApp extends Page { + + /** + * App + * + * @var App + */ + private $app; + + /** + * Do something at startup + * + * @override + */ + protected function prepare() { + + // process the request + $this->processQueryString(); + + // set the page title + $this->setTitle( __( "App" ) ); + + // check if we should do the App + if( $this->isAppFormSubmitted() ) { + $this->processUpdate(); + } + } + + /** + * Process the Query string + */ + public function processQueryString() { + + // get the page ID + $id = $_POST['id'] ?? $_GET['id'] ?? null; + $id = (int) $id; + + if( $id ) { + + // query an App I can edit + $this->app = ( new QueryAppUser() ) + ->joinApp() + ->whereAppID( $id ) + ->whereUserIsMe() + ->queryRow(); + + // no app (or not mine) no party + if( !$this->app ) { + page_not_found(); + } + + } else { + // missing App ID - want to create an App + require_permission( 'add-app' ); + } + } + + /** + * Process the App update + */ + public function processUpdate() { + + $data = []; + + $name = $_POST['name'] ?? null; + $name = (string) $name; + + // update the name if provided + if( $name ) { + $data['app_name'] = $name; + } + + if( $data ) { + if( $this->app ) { + + // update existing App + ( new QueryApp() ) + ->whereApp( $this->app ) + ->update( $data ); + + $id = $this->app->getAppID(); + } else { + + // insert a new App + + query( 'START TRANSACTION' ); + + // insert new App + ( new QueryApp() ) + ->insertRow( $data ); + + // ID of this App + $id = last_inserted_ID(); + + // associate the App to this User + ( new QueryAppUser() ) + ->insertRow( [ + 'app_ID' => $id, + 'user_ID' => get_user()->getUserID(), + ] ); + + query( 'COMMIT' ); + } + + // POST -> redirect -> GET + http_redirect( http_build_get_query( 'app.php', [ + 'id' => $id, + ] ) ); + } + } + + /** + * Check if the App form was submitted + * + * @return boolean + */ + public function isAppFormSubmitted() { + return is_action( 'save-app' ); + } + + /** + * Check if the App failed + * + * @return boolean + */ + public function isAppFormFailed() { + return $this->isAppFormSubmitted(); + } + + /** + * Get the App (if any) + * + * @return App + */ + public function getApp() { + return $this->app; + } +} diff --git a/template/form-add-app.php b/include/class-PageNotFound.php similarity index 67% copy from template/form-add-app.php copy to include/class-PageNotFound.php index 4e27e43..6bf5045 100644 --- a/template/form-add-app.php +++ b/include/class-PageNotFound.php @@ -1,34 +1,41 @@ . -?> +/** + * Page not found + */ +class PageNotFound extends Page { - -
+ /** + * @override + */ + public function prepare() { - + http_response_code( 404 ); -

-
- -

+ $this->setTitle( __( "Not Found" ) ); -

- -

-
- + } + + /** + * Print content + */ + public function printContent() { + template( 'not-found' ); + } + +} diff --git a/include/class-QueryApp.php b/include/class-QueryApp.php index 4ba6b93..cf4762b 100644 --- a/include/class-QueryApp.php +++ b/include/class-QueryApp.php @@ -1,56 +1,83 @@ . /** * Methods for a QueryApp class */ trait QueryAppTrait { + /** + * Where the App is... + * + * @param object $app + * @return self + */ + public function whereApp( $app ) { + return $this->whereAppID( $app->getAppID() ); + } + + /** + * Where the App ID is... + * + * @param int $id + * @return self + */ + public function whereAppID( $id ) { + return $this->whereInt( $this->APP_ID, $id ); + } + /** * Join a table with the App table * * @return */ public function joinApp( $type = 'INNER' ) { return $this->joinOn( $type, 'app', 'app.app_ID', $this->APP_ID ); } } /** * Execute a Query against an App */ class QueryApp extends Query { use QueryAppTrait; + /** + * Univoque App ID column name + * + * @var string + */ + protected $APP_ID = 'app.app_ID'; + /** * Constructor * * @param object $db Database connection * @param string $class_name Default class name for the results */ public function __construct( $db = null, $class_name = 'App' ) { // set the database connection and the default class name for the results parent::__construct( $db, $class_name ); // set FROM table $this->from( 'app' ); } } diff --git a/include/class-QueryAppUser.php b/include/class-QueryAppUser.php index 440b5c9..93a302b 100644 --- a/include/class-QueryAppUser.php +++ b/include/class-QueryAppUser.php @@ -1,55 +1,55 @@ . /** * Execute a Query against the 'appuser' table */ class QueryAppUser extends Query { use QueryAppTrait; use QueryUserTrait; /** * Univoque User ID column name * * @var string */ protected $USER_ID = 'appuser.user_ID'; /** * Univoque App ID column name * * @var string */ - protected $APP_ID = 'app.app_ID'; + protected $APP_ID = 'appuser.app_ID'; /** * Constructor * * @param object $db Database connection * @param string $class_name Default class name for the results */ - public function __construct( $db = null, $class_name = 'Queried' ) { + public function __construct( $db = null, $class_name = 'App' ) { // set the database connection and the default class name for the results parent::__construct( $db, $class_name ); // set FROM table $this->from( 'appuser' ); } } diff --git a/include/functions.php b/include/functions.php index 672ee1c..921ab17 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,53 +1,75 @@ . // some functions you may want to have /** * Require a certain page from the template directory * * @param $name string Template name * @param $args array Arguments to be passed to the template scope */ function template( $name, $args = [] ) { // extract the variables from the provided array extract( $args, EXTR_SKIP ); require ABSPATH . "/template/$name.php"; } /** * Require a specific permission * * @param string $permission */ function require_permission( $permission ) { if( !has_permission( $permission ) ) { + require_more_privileges(); + } +} - if( is_logged() ) { - http_response_code( 403 ); - die( "ARE YOU A PIRATE?" ); - } - - $url = http_build_get_query( 'login.php', [ - 'redirect' => $_SERVER['REQUEST_URI'], - ] ); +/** + * Require more privileges + * + * If you are logged-in, the page dies. + * If you are not-logged-in, you will be redirected. + */ +function require_more_privileges() { - http_redirect( $url, 303 ); // HTTP 303 redirect: See Other + if( is_logged() ) { + http_response_code( 403 ); + die( "ARE YOU A PIRATE?" ); } + + $url = http_build_get_query( 'login.php', [ + 'redirect' => $_SERVER['REQUEST_URI'], + ] ); + + // HTTP 303 redirect: See Other + http_redirect( $url, 303 ); +} + +/** + * Spawn a page not found page + */ +function page_not_found() { + $page = new PageNotFound(); + $page->printHeader(); + $page->printContent(); + $page->printFooter(); + exit; } diff --git a/template/form-add-app.php b/template/form-app.php similarity index 69% copy from template/form-add-app.php copy to template/form-app.php index 4e27e43..841a137 100644 --- a/template/form-add-app.php +++ b/template/form-app.php @@ -1,34 +1,52 @@ . +/* + * This is the template to change an App + * + * Available variables: + * + * $app (App|null) + */ ?>


- + getAppName() ); + } + ?> />

+ + getAppID() ) ?> /> + +

- +

diff --git a/template/form-add-app.php b/template/not-found.php similarity index 67% rename from template/form-add-app.php rename to template/not-found.php index 4e27e43..15f2ff3 100644 --- a/template/form-add-app.php +++ b/template/not-found.php @@ -1,34 +1,23 @@ . -?> - - -
- - +/* + * This template for the page not found + */ -

-
- -

- -

- -

-
- +?> +

diff --git a/www/index.php b/www/app.php similarity index 70% copy from www/index.php copy to www/app.php index d14a50d..f4e9220 100644 --- a/www/index.php +++ b/www/app.php @@ -1,44 +1,40 @@ . // load everything require '../load.php'; // this is the homepage (the business logic of this page it's in this class) -$page = new PageHome(); - -// I want this stylesheet -enqueue_css( 'my-style' ); +$page = new PageApp(); // print site header $page->printHeader(); ?> -

- areThereMyApps() ): ?> - getMyApps() as $app ): ?> - getAppName() ) ?> - - -

+ + isAppFormSubmitted() ): ?> +
+

+
-

- + $page->getApp(), + ] ) ?> printFooter(); diff --git a/www/index.php b/www/index.php index d14a50d..270505b 100644 --- a/www/index.php +++ b/www/index.php @@ -1,44 +1,56 @@ . // load everything require '../load.php'; // this is the homepage (the business logic of this page it's in this class) $page = new PageHome(); // I want this stylesheet enqueue_css( 'my-style' ); // print site header $page->printHeader(); ?>

areThereMyApps() ): ?> + -

+

- + null, + ] ) ?> printFooter();