Week5: Using Twig (Change Calculator)

This commit is contained in:
Llewellyn van der Merwe 2022-04-25 03:53:43 +02:00
parent cd9ab64650
commit c07b1c984c
Signed by: Llewellyn
GPG Key ID: EFC0C720A240551C
58 changed files with 824 additions and 3991 deletions

View File

@ -2,7 +2,6 @@
.idea
# Local System File
config.php
php.ini
# Vendor directory handling

View File

@ -1,52 +0,0 @@
###########################################
# ======= Enable the Rewrite Engine =======
RewriteEngine On
###########################################
###########################################
# ======= No directory listings =======
IndexIgnore *
Options +FollowSymLinks
Options -Indexes
###########################################
###########################################
# ======== Remove multiple slashes ========
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]
###########################################
###########################################
# ======== Remove trailing slashes ========
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
###########################################
###########################################
# ======== SEF URL Routing ========
# If the request is not for a static asset
RewriteCond %{REQUEST_URI} !^/media/
# Or for a file that exists in the web directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite the request to run the application
RewriteRule (.*) index.php
###########################################

View File

@ -1,10 +1,10 @@
{
"name": "sport/stars",
"name": "change/calculator",
"type": "project",
"description": "Sport Stars",
"description": "Change Calculator",
"keywords": [
"sport",
"star"
"change",
"calculator"
],
"homepage": "https://github.com/mychamplain",
"license": "GPL-2.0-or-later",
@ -21,7 +21,7 @@
},
"autoload": {
"psr-4": {
"Sport\\Stars\\": "libraries/src/"
"Change\\Calculator\\": "libraries/src/"
}
},
"require": {
@ -29,12 +29,7 @@
"ext-json": "*",
"joomla/application": "~2.0",
"joomla/archive": "~2.0",
"joomla/authentication": "~2.0",
"joomla/console": "~2.0",
"joomla/controller": "~2.0",
"joomla/crypt": "~2.0",
"joomla/data": "~2.0",
"joomla/database": "~2.0",
"joomla/di": "~2.0",
"joomla/event": "~2.0",
"joomla/filter": "~2.0",
@ -44,12 +39,9 @@
"joomla/model": "~2.0",
"joomla/preload": "~2.0",
"joomla/ldap": "~2.0",
"joomla/oauth1": "~2.0",
"joomla/oauth2": "~2.0",
"joomla/registry": "~2.0",
"joomla/renderer": "~2.0",
"joomla/router": "~2.0",
"joomla/session": "~2.0",
"joomla/string": "~2.0",
"joomla/uri": "~2.0",
"joomla/utilities": "~2.0",
@ -63,10 +55,7 @@
"defuse/php-encryption": "^2.0",
"symfony/asset": "^5.1.2",
"symfony/process": "^5.1.2",
"symfony/web-link": "^5.1.2",
"symfony/yaml": "^5.1.2",
"theiconic/php-ga-measurement-protocol": "^2.7.2",
"twig/twig": "^2.13",
"phpmailer/phpmailer": "~6.0"
"twig/intl-extra": "^3.3.5"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,41 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
* -------------------------------------------------------------------------
* THIS SHOULD ONLY BE USED AS A LAST RESORT WHEN THE WEB INSTALLER FAILS
*
* If you are installing Sport Stars! manually ie not using the web browser installer
* then rename this file to config.php eg
*
* UNIX -> mv config.php.example config.php
* Windows -> rename config.php.example config.php
*
* Now edit this file and configure the parameters for your site and
* database.
*
* Finally move this file to the root folder of your Sport Stars installation eg
*
* UNIX -> mv config.php ../
* Windows -> copy config.php ../
*
* SOURCE: https://github.com/joomla/joomla-cms/blob/4.1-dev/installation/configuration.php-dist
*
*/
class LConfig
{
public $sitename = 'Sport Stars!'; // Name of Sport Stars site
/* Database Settings */
public $dbtype = 'mysqli'; // Normally mysqli
public $host = 'localhost'; // This is normally set to localhost
public $user = ''; // Database username
public $password = ''; // Database password
public $db = ''; // Database name
public $dbprefix = 'homework_'; // LEAVE THIS UNCHANGED FOR NOW
}

View File

@ -1,52 +0,0 @@
###########################################
# ======= Enable the Rewrite Engine =======
RewriteEngine On
###########################################
###########################################
# ======= No directory listings =======
IndexIgnore *
Options +FollowSymLinks
Options -Indexes
###########################################
###########################################
# ======== Remove multiple slashes ========
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]
###########################################
###########################################
# ======== Remove trailing slashes ========
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
###########################################
###########################################
# ======== SEF URL Routing ========
# If the request is not for a static asset
RewriteCond %{REQUEST_URI} !^/media/
# Or for a file that exists in the web directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite the request to run the application
RewriteRule (.*) index.php
###########################################

View File

@ -1,15 +1,13 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
use Sport\Stars\Factory;
defined('_LEXEC') or die;
// Option to override defines from root folder
@ -44,19 +42,17 @@ require_once LPATH_BASE . '/includes/framework.php';
try
{
$container = (new Joomla\DI\Container)
->registerServiceProvider(new Sport\Stars\Service\ConfigurationProvider(LPATH_CONFIGURATION . '/config.php'))
->registerServiceProvider(new Sport\Stars\Service\InputProvider)
->registerServiceProvider(new Sport\Stars\Service\ApplicationProvider)
->registerServiceProvider(new Sport\Stars\Service\RouterProvider)
->registerServiceProvider(new Sport\Stars\Service\MVCProvider)
->registerServiceProvider(new Joomla\Database\Service\DatabaseProvider)
->registerServiceProvider(new Sport\Stars\Service\EventProvider)
->registerServiceProvider(new Sport\Stars\Service\HttpProvider)
->registerServiceProvider(new Sport\Stars\Service\LoggingProvider)
->registerServiceProvider(new Change\Calculator\Service\InputProvider)
->registerServiceProvider(new Change\Calculator\Service\ApplicationProvider)
->registerServiceProvider(new Change\Calculator\Service\RouterProvider)
->registerServiceProvider(new Change\Calculator\Service\MVCProvider)
->registerServiceProvider(new Change\Calculator\Service\EventProvider)
->registerServiceProvider(new Change\Calculator\Service\HttpProvider)
->registerServiceProvider(new Change\Calculator\Service\LoggingProvider)
->registerServiceProvider(new Joomla\Preload\Service\PreloadProvider)
->registerServiceProvider(new Sport\Stars\Service\TemplatingProvider);
->registerServiceProvider(new Change\Calculator\Service\TemplatingProvider);
// Alias the web application to Sport Stars's base application class as this is the primary application for the environment
// Alias the web application to Change Calculator's base application class as this is the primary application for the environment
$container->alias(Joomla\Application\AbstractApplication::class, Joomla\Application\AbstractWebApplication::class);
// Alias the web logger to the PSR-3 interface as this is the primary logger for the environment
@ -77,11 +73,8 @@ catch (Throwable $e)
// source: https://github.com/joomla/framework.joomla.org/blob/master/www/index.php#L85
try
{
$app = $container->get(Joomla\Application\AbstractApplication::class);
// Set the application as global app
Factory::$application = $app;
// Execute the application.
$app->execute();
$container->get(Joomla\Application\AbstractApplication::class)->execute();
}
catch (Throwable $e)
{

View File

@ -1,8 +1,8 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
@ -19,5 +19,4 @@ define('LPATH_SITE', LPATH_ROOT);
define('LPATH_CONFIGURATION', LPATH_ROOT);
define('LPATH_ADMINISTRATOR', LPATH_ROOT . DIRECTORY_SEPARATOR . 'administrator');
define('LPATH_LIBRARIES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'libraries');
define('LPATH_INSTALLATION', LPATH_ROOT . DIRECTORY_SEPARATOR . 'installation');
define('LPATH_TEMPLATES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'templates');

View File

@ -1,8 +1,8 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
@ -13,23 +13,3 @@ defined('_LEXEC') or die;
// System includes
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/framework.php#L14
require_once LPATH_LIBRARIES . '/bootstrap.php';
// Installation check, and check on removal of the installation directory.
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/framework.php#L17
if (!file_exists(LPATH_CONFIGURATION . '/config.php')
|| (filesize(LPATH_CONFIGURATION . '/config.php') < 10)
|| (file_exists(LPATH_INSTALLATION . '/index.php')))
{
if (file_exists(LPATH_INSTALLATION . '/index.php'))
{
header('Location: ' . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], 'index.php')) . 'installation/index.php');
exit;
}
else
{
echo 'No configuration file found and no installation code available. Exiting...';
exit;
}
}

View File

@ -1,8 +1,8 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt

View File

@ -1,31 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_LEXEC') or die;
// Option to override defines from root folder
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L15
if (file_exists(dirname(__DIR__) . '/defines.php'))
{
include_once dirname(__DIR__) . '/defines.php';
}
// Load the default defines
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L20
if (!defined('_LDEFINES'))
{
define('LPATH_BASE', dirname(__DIR__));
require_once LPATH_BASE . '/includes/defines.php';
}
// I have not yet had time to finish this part of the application (CMS)
echo file_get_contents(LPATH_ROOT . '/templates/system/install_notice.html');
exit;

View File

@ -1,23 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_LEXEC') or die;
// Global definitions
$parts = explode(DIRECTORY_SEPARATOR, LPATH_BASE);
array_pop($parts);
// Defines.
define('LPATH_ROOT', implode(DIRECTORY_SEPARATOR, $parts));
define('LPATH_SITE', LPATH_ROOT);
define('LPATH_CONFIGURATION', LPATH_ROOT);
define('LPATH_ADMINISTRATOR', LPATH_ROOT . DIRECTORY_SEPARATOR . 'administrator');
define('LPATH_LIBRARIES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'libraries');
define('LPATH_INSTALLATION', LPATH_ROOT . DIRECTORY_SEPARATOR . 'installation');

View File

@ -1,41 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_LEXEC') or die;
// System includes
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/administrator/includes/framework.php#L14
require_once LPATH_LIBRARIES . '/bootstrap.php';
// Installation check, and check on removal of the installation directory.
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/administrator/includes/framework.php#L17
if (!file_exists(LPATH_CONFIGURATION . '/config.php')
|| (filesize(LPATH_CONFIGURATION . '/config.php') < 10)
|| (file_exists(LPATH_INSTALLATION . '/index.php')))
{
if (file_exists(LPATH_INSTALLATION . '/index.php'))
{
header('Location: ../installation/index.php');
exit;
}
else
{
echo 'No configuration file found and no installation code available. Exiting...';
exit;
}
}
// Pre-Load configuration. Don't remove the Output Buffering due to BOM issues.
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/administrator/includes/framework.php#L36
ob_start();
require_once LPATH_CONFIGURATION . '/config.php';
ob_end_clean();

View File

@ -1,35 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
// NOTE: This file should remain compatible with PHP 5.2 to allow us to run our PHP minimum check and show a friendly error message
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/index.php#L9
// Define the application's minimum supported PHP version as a constant, so it can be referenced within the application.
define('OCTOLEO_MINIMUM_PHP', '7.2.5');
if (version_compare(PHP_VERSION, OCTOLEO_MINIMUM_PHP, '<'))
{
die(
str_replace(
'{{phpversion}}',
OCTOLEO_MINIMUM_PHP,
file_get_contents(dirname(__FILE__) . '/../templates/system/incompatible.html')
)
);
}
/**
* Constant that is checked in included files to prevent direct access.
*/
define('_LEXEC', 1);
// We must setup some house rules, since we can't have all
// this code just doing what it wants can we.... <<eWɘ>>yn growling
require_once dirname(__FILE__) . '/includes/app.php';

View File

@ -1,14 +1,14 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
use Sport\Stars\Autoload\ClassLoader;
use Change\Calculator\Autoload\ClassLoader;
defined('_LEXEC') or die;
@ -30,7 +30,7 @@ if (!class_exists('LLoader'))
// If JLoader still does not exist panic.
if (!class_exists('LLoader'))
{
throw new RuntimeException('Sport Stars Platform not loaded.');
throw new RuntimeException('Change Calculator Platform not loaded.');
}
}
@ -42,7 +42,7 @@ LLoader::setup();
$loader = require LPATH_LIBRARIES . '/vendor/autoload.php';
// We need to pull our decorated class loader into memory before unregistering Composer's loader
class_exists('\\Sport\\Stars\\Autoload\\ClassLoader');
class_exists('\\Change\\Calculator\\Autoload\\ClassLoader');
$loader->unregister();

View File

@ -1,6 +1,6 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* Joomla! Content Management System
*
@ -308,15 +308,15 @@ abstract class LLoader
}
/**
* Method to setup the autoloaders for the Sport Stars Platform.
* Method to setup the autoloaders for the Change Calculator Platform.
* Since the SPL autoloaders are called in a queue we will add our explicit
* class-registration based loader first, then fall back on the autoloader based on conventions.
* This will allow people to register a class in a specific location and override platform libraries
* as was previously possible.
*
* @param boolean $enablePsr True to enable autoloading based on PSR-0.
* @param boolean $enablePrefixes True to enable prefix based class loading (needed to auto load the Sport Stars core).
* @param boolean $enableClasses True to enable class map based class loading (needed to auto load the Sport Stars core).
* @param boolean $enablePrefixes True to enable prefix based class loading (needed to auto load the Change Calculator core).
* @param boolean $enableClasses True to enable class map based class loading (needed to auto load the Change Calculator core).
*
* @return void
*

View File

@ -1,19 +1,17 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Application;
namespace Change\Calculator\Application;
use Joomla\Application\AbstractWebApplication;
use Joomla\Application\Controller\ControllerResolverInterface;
use Joomla\Application\SessionAwareWebApplicationInterface;
use Joomla\Application\SessionAwareWebApplicationTrait;
use Joomla\Application\Web\WebClient;
use Joomla\Input\Input;
use Joomla\Registry\Registry;
@ -25,9 +23,8 @@ use function call_user_func;
* Site application class
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/WebApplication.php
*/
class SportStarsApplication extends AbstractWebApplication implements SessionAwareWebApplicationInterface
class ChangeCalculatorApplication extends AbstractWebApplication
{
use SessionAwareWebApplicationTrait;
/**
* The application's controller resolver.
@ -48,20 +45,17 @@ class SportStarsApplication extends AbstractWebApplication implements SessionAwa
*
* @param ControllerResolverInterface $controllerResolver The application's controller resolver
* @param RouterInterface $router The application's router
* @param Input $input An optional argument to provide dependency injection for the application's
* @param Input|null $input An optional argument to provide dependency injection for the application's
* input object.
* @param Registry $config An optional argument to provide dependency injection for the application's
* config object.
* @param WebClient $client An optional argument to provide dependency injection for the application's
* @param WebClient|null $client An optional argument to provide dependency injection for the application's
* client object.
* @param ResponseInterface $response An optional argument to provide dependency injection for the application's
* @param ResponseInterface|null $response An optional argument to provide dependency injection for the application's
* response object.
*/
public function __construct(
ControllerResolverInterface $controllerResolver,
RouterInterface $router,
Input $input = null,
Registry $config = null,
WebClient $client = null,
ResponseInterface $response = null
)
@ -70,7 +64,7 @@ class SportStarsApplication extends AbstractWebApplication implements SessionAwa
$this->router = $router;
// Call the constructor as late as possible (it runs `initialise`).
parent::__construct($input, $config, $client, $response);
parent::__construct($input, null, $client, $response);
}
/**

View File

@ -1,71 +0,0 @@
<?php
/**
* Joomla! Framework Website
*
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Asset;
use Symfony\Component\Asset\Context\ContextInterface;
use Symfony\Component\Asset\Package;
use Symfony\Component\Asset\PathPackage;
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
/**
* Extended path package for resolving assets from a Laravel Mix manifest
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Asset/MixPathPackage.php
*/
class MixPathPackage extends PathPackage
{
/**
* Decorated Package instance
*
* @var Package
*/
private $decoratedPackage;
/**
* Constructor
*
* @param Package $decoratedPackage Decorated Package instance
* @param string $basePath The base path to be prepended to relative paths
* @param VersionStrategyInterface $versionStrategy The version strategy
* @param ContextInterface $context The context
*/
public function __construct(
Package $decoratedPackage,
string $basePath,
VersionStrategyInterface $versionStrategy,
ContextInterface $context = null
) {
parent::__construct($basePath, $versionStrategy, $context);
$this->decoratedPackage = $decoratedPackage;
}
/**
* Returns an absolute or root-relative public path.
*
* @param string $path A path
*
* @return string The public path
*/
public function getUrl($path)
{
if ($this->isAbsoluteUrl($path))
{
return $path;
}
$versionedPath = $this->getVersionStrategy()->applyVersion("/$path");
if ($versionedPath === $path)
{
return $this->decoratedPackage->getUrl($path);
}
return $this->getBasePath() . ltrim($versionedPath, '/');
}
}

View File

@ -6,7 +6,7 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Autoload;
namespace Change\Calculator\Autoload;
defined('_LEXEC') or die;
@ -15,7 +15,7 @@ use LLoader;
use function defined;
/**
* Decorate Composer ClassLoader for Sport Stars!
* Decorate Composer ClassLoader for Change Calculator!
*
* For backward compatibility due to class aliasing in the CMS, the loadClass() method was modified to call
* the LLoader::applyAliasFor() method.

View File

@ -1,47 +1,47 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Controller;
namespace Change\Calculator\Controller;
use Exception;
use Joomla\Application\AbstractApplication;
use Joomla\Controller\AbstractController;
use Joomla\Input\Input;
use Sport\Stars\Application\SportStarsApplication;
use Sport\Stars\View\TableHtmlView;
use Change\Calculator\Application\ChangeCalculatorApplication;
use Change\Calculator\View\CalculatorHtmlView;
use Laminas\Diactoros\Response\HtmlResponse;
/**
* Controller handling the site's dashboard
*
* @method SportStarsApplication getApplication() Get the application object.
* @property-read SportStarsApplication $app Application object
* @method ChangeCalculatorApplication getApplication() Get the application object.
* @property-read ChangeCalculatorApplication $app Application object
*/
class TableController extends AbstractController
class CalculatorController extends AbstractController
{
/**
* The view object.
*
* @var TableHtmlView
* @var CalculatorHtmlView
*/
private $view;
/**
* Constructor.
*
* @param TableHtmlView $view The view object.
* @param Input $input The input object.
* @param AbstractApplication $app The application object.
* @param CalculatorHtmlView $view The view object.
* @param Input|null $input The input object.
* @param AbstractApplication|null $app The application object.
*/
public function __construct(TableHtmlView $view, Input $input = null, AbstractApplication $app = null)
public function __construct(CalculatorHtmlView $view, Input $input = null, AbstractApplication $app = null)
{
parent::__construct($input, $app);
@ -59,6 +59,10 @@ class TableController extends AbstractController
// Do not Enable browser caching
$this->getApplication()->allowCache(false);
// get the input
$this->view->setCost($this->getInput()->getFloat('cost', 0.00));
$this->view->setPayment($this->getInput()->getFloat('payment', 0.00));
// render the table
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));

View File

@ -1,185 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Controller;
use Exception;
use Joomla\Application\AbstractApplication;
use Joomla\Controller\AbstractController;
use Joomla\Input\Input;
use Joomla\String\StringHelper;
use Joomla\Uri\Uri;
use Sport\Stars\Application\SportStarsApplication;
use Sport\Stars\Model\EditModel;
use Sport\Stars\View\EditHtmlView;
use Laminas\Diactoros\Response\HtmlResponse;
/**
* Controller handling the edit area
*
* @method SportStarsApplication getApplication() Get the application object.
* @property-read SportStarsApplication $app Application object
*/
class EditController extends AbstractController
{
/**
* The page model object.
*
* @var EditModel
*/
private $model;
/**
* The view object.
*
* @var EditHtmlView
*/
private $view;
/**
* Constructor.
*
* @param EditModel $model The page model object.
* @param EditHtmlView $view The view object.
* @param Input $input The input object.
* @param AbstractApplication $app The application object.
*/
public function __construct(EditModel $model, EditHtmlView $view, Input $input = null, AbstractApplication $app = null)
{
parent::__construct($input, $app);
$this->model = $model;
$this->view = $view;
}
/**
* Execute the controller.
*
* @return boolean
* @throws Exception
*/
public function execute(): bool
{
// Do not Enable browser caching
$this->getApplication()->allowCache(false);
$method = $this->getInput()->getMethod();
$id = $this->getInput()->getInt('id', 0);
$task = $this->getInput()->getString('task', '');
// if task is delete
if ('delete' === $task)
{
// delete the item
if ($id > 0 && $this->model->delete($id))
{
$this->model->enqueueMessage('Item was deleted!', 'success');
}
else
{
$this->model->enqueueMessage('Item could not be deleted!', 'error');
}
// go to set page
$this->redirect();
return true;
}
if ('POST' === $method)
{
$id = $this->setItem();
}
$this->view->setActiveItem($id);
// check if user is allowed to access
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
return true;
}
/**
* Set an item
*
*
* @return int
* @throws \Exception
*/
protected function setItem(): int
{
// get the post
$post = $this->getInput()->getInputForRequestMethod();
// we get all the needed items
$tempItem = [];
$tempItem['id'] = $post->getInt('item_id', 0);
$tempItem['name'] = $post->getString('name', '');
$tempItem['age'] = $post->getInt('age', 0);
$tempItem['sport'] = $post->getString('sport', '');
// check that we have a Title
$can_save = true;
if (empty($tempItem['name']) || is_numeric($tempItem['name']) || StringHelper::strlen($tempItem['name']) > 100)
{
// we show a warning message
$tempItem['name'] = '';
$this->model->enqueueMessage('Name field is required.', 'error');
$can_save = false;
}
// we actually can also not continue if we don't have age
if (empty($tempItem['age']) || $tempItem['age'] > 120 || $tempItem['age'] < 1)
{
// we show a warning message
$tempItem['age'] = '';
$this->model->enqueueMessage('Age field is required.', 'error');
$can_save = false;
}
// we actually can also not continue if we don't have sport
if (empty($tempItem['sport']) || is_numeric($tempItem['sport']) || StringHelper::strlen($tempItem['sport']) > 100)
{
// we show a warning message
$tempItem['sport'] = '';
$this->model->enqueueMessage('Sport field is required.', 'error');
$can_save = false;
}
// can we save the item
if ($can_save)
{
return $this->model->setItem(
$tempItem['id'],
$tempItem['name'],
$tempItem['age'],
$tempItem['sport']);
}
// add to model the post values
$this->model->tempItem = $tempItem;
return $tempItem['id'];
}
/**
* @param string|null $target
*
* @return void
*/
private function redirect()
{
// get uri request to get host
$uri = new Uri($this->getApplication()->get('uri.request'));
// fix the path
$path = $uri->getPath();
$path = substr($path, 0, strripos($path, '/'));
// redirect to the set area
$this->getApplication()->redirect($uri->getScheme() . '://' . $uri->getHost() . $path);
}
}

View File

@ -1,18 +1,18 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Controller;
namespace Change\Calculator\Controller;
use Joomla\Controller\AbstractController;
use Laminas\Diactoros\Response\TextResponse;
use Sport\Stars\Application\SiteApplication;
use Change\Calculator\Application\SiteApplication;
/**
* Controller class to display a message to individuals looking for the wrong CMS

View File

@ -1,491 +0,0 @@
<?php
/**
* Joomla! Content Management System
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Date;
use DateInterval;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use Exception;
use Joomla\Database\DatabaseInterface;
use ReturnTypeWillChange;
use Sport\Stars\Factory;
use function is_string;
/**
* Date is a class that stores a date and provides logic to manipulate
* and render that date in a variety of formats.
*
* @method Date|bool add(DateInterval $interval) Adds an amount of days, months, years, hours, minutes and seconds to a Date object.
* @method Date|bool sub(DateInterval $interval) Subtracts an amount of days, months, years, hours, minutes and seconds from a Date object.
* @method Date|bool modify(string $modify) Alter the timestamp of this object by incre/decre-menting in a format accepted by strtotime().
*
* @property-read string $daysinmonth t - Number of days in the given month.
* @property-read string $dayofweek N - ISO-8601 numeric representation of the day of the week.
* @property-read string $dayofyear z - The day of the year (starting from 0).
* @property-read boolean $isleapyear L - Whether it's a leap year.
* @property-read string $day d - Day of the month, 2 digits with leading zeros.
* @property-read string $hour H - 24-hour format of an hour with leading zeros.
* @property-read string $minute i - Minutes with leading zeros.
* @property-read string $second s - Seconds with leading zeros.
* @property-read string $microsecond u - Microseconds with leading zeros.
* @property-read string $month m - Numeric representation of a month, with leading zeros.
* @property-read string $ordinal S - English ordinal suffix for the day of the month, 2 characters.
* @property-read string $week W - ISO-8601 week number of year, weeks starting on Monday.
* @property-read string $year Y - A full numeric representation of a year, 4 digits.
*
* @since 1.7.0
*/
class Date extends DateTime
{
const DAY_ABBR = "\x021\x03";
const DAY_NAME = "\x022\x03";
const MONTH_ABBR = "\x023\x03";
const MONTH_NAME = "\x024\x03";
/**
* The format string to be applied when using the __toString() magic method.
*
* @var string
* @since 1.7.0
*/
public static $format = 'Y-m-d H:i:s';
/**
* Placeholder for a \DateTimeZone object with GMT as the time zone.
*
* @var object
* @since 1.7.0
*
* @deprecated 5.0 Without replacement
*/
protected static $gmt;
/**
* Placeholder for a \DateTimeZone object with the default server
* time zone as the time zone.
*
* @var object
* @since 1.7.0
*
* @deprecated 5.0 Without replacement
*/
protected static $stz;
/**
* The \DateTimeZone object for usage in rending dates as strings.
*
* @var DateTimeZone
* @since 3.0.0
*/
protected $tz;
/**
* Constructor.
*
* @param string $date String in a format accepted by strtotime(), defaults to "now".
* @param mixed $tz Time zone to be used for the date. Might be a string or a DateTimeZone object.
*
* @since 1.7.0
*/
public function __construct($date = 'now', $tz = null)
{
// Create the base GMT and server time zone objects.
if (empty(self::$gmt) || empty(self::$stz))
{
// @TODO: This code block stays here only for B/C, can be removed in 5.0
self::$gmt = new DateTimeZone('GMT');
self::$stz = new DateTimeZone(@date_default_timezone_get());
}
// If the time zone object is not set, attempt to build it.
if (!($tz instanceof DateTimeZone))
{
if (is_string($tz))
{
$tz = new DateTimeZone($tz);
}
else
{
$tz = new DateTimeZone('UTC');
}
}
// Backup active time zone
$activeTZ = date_default_timezone_get();
// Force UTC timezone for correct time handling
date_default_timezone_set('UTC');
// If the date is numeric assume a unix timestamp and convert it.
$date = is_numeric($date) ? date('c', $date) : $date;
// Call the DateTime constructor.
parent::__construct($date, $tz);
// Restore previously active timezone
date_default_timezone_set($activeTZ);
// Set the timezone object for access later.
$this->tz = $tz;
}
/**
* Magic method to access properties of the date given by class to the format method.
*
* @param string $name The name of the property.
*
* @return mixed A value if the property name is valid, null otherwise.
*
* @since 1.7.0
*/
public function __get($name)
{
$value = null;
switch ($name)
{
case 'daysinmonth':
$value = $this->format('t', true);
break;
case 'dayofweek':
$value = $this->format('N', true);
break;
case 'dayofyear':
$value = $this->format('z', true);
break;
case 'isleapyear':
$value = (boolean) $this->format('L', true);
break;
case 'day':
$value = $this->format('d', true);
break;
case 'hour':
$value = $this->format('H', true);
break;
case 'minute':
$value = $this->format('i', true);
break;
case 'second':
$value = $this->format('s', true);
break;
case 'month':
$value = $this->format('m', true);
break;
case 'ordinal':
$value = $this->format('S', true);
break;
case 'week':
$value = $this->format('W', true);
break;
case 'year':
$value = $this->format('Y', true);
break;
default:
$trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'],
E_USER_NOTICE
);
}
return $value;
}
/**
* Magic method to render the date object in the format specified in the public
* static member Date::$format.
*
* @return string The date as a formatted string.
*
* @since 1.7.0
*/
public function __toString()
{
return (string) parent::format(self::$format);
}
/**
* Proxy for new Date().
*
* @param string $date String in a format accepted by strtotime(), defaults to "now".
* @param mixed $tz Time zone to be used for the date.
*
* @return Date
*
* @since 1.7.3
*/
public static function getInstance($date = 'now', $tz = null)
{
return new static($date, $tz);
}
/**
* Translates day of week number to a string.
*
* @param integer $day The numeric day of the week.
* @param boolean $abbr Return the abbreviated day string?
*
* @return string The day of the week.
*
* @since 1.7.0
*/
public function dayToString($day, $abbr = false)
{
switch ($day)
{
case 0:
return $abbr ? 'Sun' : 'Sunday';
case 1:
return $abbr ? 'Mon' : 'Monday';
case 2:
return $abbr ? 'Tue' : 'Tuesday';
case 3:
return $abbr ? 'Wed' : 'Wednesday';
case 4:
return $abbr ? 'Thu' : 'Thursday';
case 5:
return $abbr ? 'Fri' : 'Friday';
case 6:
return $abbr ? 'Sat' : 'Saturday';
}
}
/**
* Gets the date as a formatted string in a local calendar.
*
* @param string $format The date format specification string (see {@link PHP_MANUAL#date})
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
* @param boolean $translate True to translate localised strings
*
* @return string The date string in the specified format format.
*
* @since 1.7.0
*/
public function calendar($format, $local = false, $translate = true)
{
return $this->format($format, $local, $translate);
}
/**
* Gets the date as a formatted string.
*
* @param string $format The date format specification string (see {@link PHP_MANUAL#date})
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
* @param boolean $translate True to translate localised strings
*
* @return string The date string in the specified format format.
*
* @since 1.7.0
*/
#[ReturnTypeWillChange]
public function format($format, $local = false, $translate = true)
{
if ($translate)
{
// Do string replacements for date format options that can be translated.
$format = preg_replace('/(^|[^\\\])D/', "\\1" . self::DAY_ABBR, $format);
$format = preg_replace('/(^|[^\\\])l/', "\\1" . self::DAY_NAME, $format);
$format = preg_replace('/(^|[^\\\])M/', "\\1" . self::MONTH_ABBR, $format);
$format = preg_replace('/(^|[^\\\])F/', "\\1" . self::MONTH_NAME, $format);
}
// If the returned time should not be local use UTC.
if ($local == false)
{
parent::setTimezone(new DateTimeZone('UTC'));
}
// Format the date.
$return = parent::format($format);
if ($translate)
{
// Manually modify the month and day strings in the formatted time.
if (strpos($return, self::DAY_ABBR) !== false)
{
$return = str_replace(self::DAY_ABBR, $this->dayToString(parent::format('w'), true), $return);
}
if (strpos($return, self::DAY_NAME) !== false)
{
$return = str_replace(self::DAY_NAME, $this->dayToString(parent::format('w')), $return);
}
if (strpos($return, self::MONTH_ABBR) !== false)
{
$return = str_replace(self::MONTH_ABBR, $this->monthToString(parent::format('n'), true), $return);
}
if (strpos($return, self::MONTH_NAME) !== false)
{
$return = str_replace(self::MONTH_NAME, $this->monthToString(parent::format('n')), $return);
}
}
if ($local == false && $this->tz !== null)
{
parent::setTimezone($this->tz);
}
return $return;
}
/**
* Get the time offset from GMT in hours or seconds.
*
* @param boolean $hours True to return the value in hours.
*
* @return float The time offset from GMT either in hours or in seconds.
*
* @since 1.7.0
*/
public function getOffsetFromGmt($hours = false)
{
return (float) $hours ? ($this->tz->getOffset($this) / 3600) : $this->tz->getOffset($this);
}
/**
* Translates month number to a string.
*
* @param integer $month The numeric month of the year.
* @param boolean $abbr If true, return the abbreviated month string
*
* @return string The month of the year.
*
* @since 1.7.0
*/
public function monthToString($month, $abbr = false)
{
switch ($month)
{
case 1:
return $abbr ? 'Jan' : 'January'; //
case 2:
return $abbr ? 'Feb' : 'February';
case 3:
return $abbr ? 'Mar' : 'March';
case 4:
return $abbr ? 'Apr' : 'April';
case 5:
return 'May';
case 6:
return $abbr ? 'Jun' : 'June';
case 7:
return $abbr ? 'Jul' : 'July';
case 8:
return $abbr ? 'Aug' : 'August';
case 9:
return $abbr ? 'Sep' : 'September';
case 10:
return $abbr ? 'Oct' : 'October';
case 11:
return $abbr ? 'Nov' : 'November';
case 12:
return $abbr ? 'Dec' : 'December';
}
}
/**
* Method to wrap the setTimezone() function and set the internal time zone object.
*
* @param DateTimeZone $tz The new \DateTimeZone object.
*
* @return Date
*
* @since 1.7.0
* @note This method can't be type hinted due to a PHP bug: https://bugs.php.net/bug.php?id=61483
*/
#[ReturnTypeWillChange]
public function setTimezone($tz)
{
$this->tz = $tz;
return parent::setTimezone($tz);
}
/**
* Gets the date as an ISO 8601 string. IETF RFC 3339 defines the ISO 8601 format
* and it can be found at the IETF Web site.
*
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
*
* @return string The date string in ISO 8601 format.
*
* @link http://www.ietf.org/rfc/rfc3339.txt
* @since 1.7.0
*/
public function toISO8601($local = false)
{
return $this->format(DateTimeInterface::RFC3339, $local, false);
}
/**
* Gets the date as an SQL datetime string.
*
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
* @param DatabaseInterface $db The database driver or null to use Factory::getDbo()
*
* @return string The date string in SQL datetime format.
*
* @throws Exception
* @since 2.5.0
* @link http://dev.mysql.com/doc/refman/5.0/en/datetime.html
*/
public function toSql($local = false, DatabaseInterface $db = null)
{
if ($db === null)
{
/** @var DatabaseInterface $db */
$db = Factory::getContainer()->get(DatabaseInterface::class);
}
return $this->format($db->getDateFormat(), $local, false);
}
/**
* Gets the date as an RFC 822 string. IETF RFC 2822 supercedes RFC 822 and its definition
* can be found at the IETF Web site.
*
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
*
* @return string The date string in RFC 822 format.
*
* @link http://www.ietf.org/rfc/rfc2822.txt
* @since 1.7.0
*/
public function toRFC822($local = false)
{
return $this->format(DateTimeInterface::RFC2822, $local, false);
}
/**
* Gets the date as UNIX time stamp.
*
* @return integer The date as a UNIX timestamp.
*
* @since 1.7.0
*/
public function toUnix()
{
return (int) parent::format('U');
}
}

View File

@ -6,14 +6,12 @@
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\EventListener;
namespace Change\Calculator\EventListener;
use Change\Calculator\Application\ChangeCalculatorApplication;
use Joomla\Application\ApplicationEvents;
use Joomla\Application\Event\ApplicationErrorEvent;
use Joomla\Console\ConsoleEvents;
use Joomla\Console\Event\ApplicationErrorEvent as ConsoleApplicationErrorEvent;
use Joomla\Event\SubscriberInterface;
use Sport\Stars\Application\SiteApplication;
use Joomla\Renderer\RendererInterface;
use Joomla\Router\Exception\MethodNotAllowedException;
use Joomla\Router\Exception\RouteNotFoundException;
@ -57,23 +55,10 @@ class ErrorSubscriber implements SubscriberInterface, LoggerAwareInterface
public static function getSubscribedEvents(): array
{
return [
ApplicationEvents::ERROR => 'handleWebError',
ConsoleEvents::APPLICATION_ERROR => 'handleConsoleError',
ApplicationEvents::ERROR => 'handleWebError'
];
}
/**
* Handle console application errors.
*
* @param ConsoleApplicationErrorEvent $event Event object
*
* @return void
*/
public function handleConsoleError(ConsoleApplicationErrorEvent $event): void
{
$this->logError($event->getError());
}
/**
* Handle web application errors.
*
@ -83,7 +68,7 @@ class ErrorSubscriber implements SubscriberInterface, LoggerAwareInterface
*/
public function handleWebError(ApplicationErrorEvent $event): void
{
/** @var SiteApplication $app */
/** @var ChangeCalculatorApplication $app */
$app = $event->getApplication();
switch (true)
@ -145,7 +130,7 @@ class ErrorSubscriber implements SubscriberInterface, LoggerAwareInterface
*/
private function prepareResponse(ApplicationErrorEvent $event): void
{
/** @var SiteApplication $app */
/** @var ChangeCalculatorApplication $app */
$app = $event->getApplication();
$app->allowCache(false);

View File

@ -1,302 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars;
defined('LPATH_PLATFORM') or die;
use Exception;
use Joomla\Application\WebApplicationInterface;
use Joomla\Database\Service\DatabaseProvider;
use Joomla\DI\Container;
use Joomla\Registry\Registry;
use LConfig;
use PHPMailer\PHPMailer\Exception as phpmailerException;
use function defined;
/**
* Sport Stars Platform Factory class.
*
* @since 1.0.0
*
* SOURCE: https://github.com/joomla/joomla-cms/blob/4.1-dev/libraries/src/Factory.php#L39
*/
abstract class Factory
{
/**
* Global application object
*
* @var WebApplicationInterface
* @since 1.0.0
*/
public static $application = null;
/**
* Global configuration object
*
* @var LConfig
* @since 1.0.0
*/
public static $config = null;
/**
* Global container object
*
* @var Container
* @since 1.0.0
*/
public static $container = null;
/**
* Global mailer object
*
* @var Mail
* @since 1.0.0
*/
public static $mailer = null;
/**
* Get the global application object. When the global application doesn't exist, an exception is thrown.
*
* @return WebApplicationInterface object
*
* @since 1.0.0
* @throws Exception
*/
public static function getApplication() : WebApplicationInterface
{
if (!self::$application)
{
throw new Exception('Failed to start application', 500);
}
return self::$application;
}
/**
* Get a container object
*
* Returns the global service container object, only creating it if it doesn't already exist.
*
* This method is only suggested for use in code whose responsibility is to create new services
* and needs to be able to resolve the dependencies, and should therefore only be used when the
* container is not accessible by other means. Valid uses of this method include:
*
* - A static `getInstance()` method calling a factory service from the container,
* see `Joomla\CMS\Toolbar\Toolbar::getInstance()` as an example
* - An application front controller loading and executing the Joomla application class,
* see the `cli/joomla.php` file as an example
* - Retrieving optional constructor dependencies when not injected into a class during a transitional
* period to retain backward compatibility, in this case a deprecation notice should also be emitted to
* notify developers of changes needed in their code
*
* This method is not suggested for use as a one-for-one replacement of static calls, such as
* replacing calls to `Factory::getDbo()` with calls to `Factory::getContainer()->get('db')`, code
* should be refactored to support dependency injection instead of making this change.
*
* @return Container
*
* @since 4.0.0
*/
public static function getContainer(): Container
{
if (!self::$container)
{
self::$container = self::createContainer();
}
return self::$container;
}
/**
* Get a mailer object.
*
* Returns the global {@link Mail} object, only creating it if it doesn't already exist.
*
* @return Mail object
*
* @see Mail
* @since 1.7.0
*/
public static function getMailer()
{
if (!self::$mailer)
{
self::$mailer = self::createMailer();
}
$copy = clone self::$mailer;
return $copy;
}
/**
* Create a container object
*
* @return Container
*
* @since 4.0.0
*/
protected static function createContainer(): Container
{
return (new Container)
->registerServiceProvider(new Service\ConfigurationProvider(LPATH_CONFIGURATION . '/octoconfig.php'))
->registerServiceProvider(new Service\InputProvider)
->registerServiceProvider(new DatabaseProvider)
->registerServiceProvider(new Service\EventProvider)
->registerServiceProvider(new Service\HttpProvider)
->registerServiceProvider(new Service\LoggingProvider);
}
/**
* Get a configuration object
*
* Returns the global {@link \JConfig} object, only creating it if it doesn't already exist.
*
* @param string $file The path to the configuration file
* @param string $type The type of the configuration file
* @param string $namespace The namespace of the configuration file
*
* @return Registry
*
* @see Registry
* @since 1.1.1
*/
public static function getConfig($file = null, $type = 'PHP', $namespace = '')
{
/**
* If there is an application object, fetch the configuration from there.
* Check it's not null because LanguagesModel can make it null and if it's null
* we would want to re-init it from configuration.php.
*/
if (self::$application && self::$application->getConfig() !== null)
{
return self::$application->getConfig();
}
if (!self::$config)
{
if ($file === null)
{
$file = JPATH_CONFIGURATION . '/octoconfig.php';
}
self::$config = self::createConfig($file, $type, $namespace);
}
return self::$config;
}
/**
* Create a configuration object
*
* @param string $file The path to the configuration file.
* @param string $type The type of the configuration file.
* @param string $namespace The namespace of the configuration file.
*
* @return Registry
*
* @see Registry
* @since 1.0.0
*/
protected static function createConfig($file, $type = 'PHP', $namespace = '')
{
if (is_file($file))
{
include_once $file;
}
// Create the registry with a default namespace of config
$registry = new Registry;
// Sanitize the namespace.
$namespace = ucfirst((string) preg_replace('/[^A-Z_]/i', '', $namespace));
// Build the config name.
$name = 'LConfig' . $namespace;
// Handle the PHP configuration type.
if ($type === 'PHP' && class_exists($name))
{
// Create the LConfig object
$config = new $name;
// Load the configuration values into the registry
$registry->loadObject($config);
}
return $registry;
}
/**
* Create a mailer object
*
* @return Mail object
*
* @see Mail
* @since 1.0.0
*/
protected static function createMailer()
{
// $conf = self::getConfig();
//
// $smtpauth = ($conf->get('smtpauth') == 0) ? null : 1;
// $smtpuser = $conf->get('smtpuser');
// $smtppass = $conf->get('smtppass');
// $smtphost = $conf->get('smtphost');
// $smtpsecure = $conf->get('smtpsecure');
// $smtpport = $conf->get('smtpport');
// $mailfrom = $conf->get('mailfrom');
// $fromname = $conf->get('fromname');
// $mailer = $conf->get('mailer');
//
// // Create a Mail object
// $mail = Mail::getInstance();
//
// // Clean the email address
// $mailfrom = MailHelper::cleanLine($mailfrom);
//
// // Set default sender without Reply-to if the mailfrom is a valid address
// if (MailHelper::isEmailAddress($mailfrom))
// {
// // Wrap in try/catch to catch phpmailerExceptions if it is throwing them
// try
// {
// // Check for a false return value if exception throwing is disabled
// if ($mail->setFrom($mailfrom, MailHelper::cleanLine($fromname), false) === false)
// {
// Log::add(__METHOD__ . '() could not set the sender data.', Log::WARNING, 'mail');
// }
// }
// catch (phpmailerException $e)
// {
// Log::add(__METHOD__ . '() could not set the sender data.', Log::WARNING, 'mail');
// }
// }
//
// // Default mailer is to use PHP's mail function
// switch ($mailer)
// {
// case 'smtp':
// $mail->useSmtp($smtpauth, $smtphost, $smtpuser, $smtppass, $smtpsecure, $smtpport);
// break;
//
// case 'sendmail':
// $mail->isSendmail();
// break;
//
// default:
// $mail->isMail();
// break;
// }
//
// return $mail;
}
}

View File

@ -6,9 +6,9 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Filter;
namespace Change\Calculator\Filter;
use Sport\Stars\String\PunycodeHelper;
use Change\Calculator\String\PunycodeHelper;
use Joomla\Filter\InputFilter as BaseInputFilter;
use function chr;
use function count;

View File

@ -0,0 +1,341 @@
<?php
/**
* @package Change Calculator
*
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Change\Calculator\Model;
/**
* Model class for calculations
*/
class CalculatorModel
{
const MSG_INFO = 'info';
/**
* @var array
*/
private $values = [];
/**
* @var array
*/
private $messages = [];
/**
* Get the change
*
* @param float $cost
* @param float $payment
*
* @return array
*/
public function getChange(float $cost, float $payment): array
{
if (empty($cost) && empty($payment))
{
// show a heads-up message
$this->enqueueMessage('Add your transaction cost and payment received values', 'info');
// return no change
return [];
}
// check that we have a cost value
elseif (empty($cost))
{
// show a warning message
$this->enqueueMessage('Add a transaction cost value', 'warning');
// keep payment
$this->values['payment'] = $payment;
// return no change
return [];
}
// check that we have a payment value
elseif (empty($payment))
{
// show a warning message
$this->enqueueMessage('Add a payment received value', 'warning');
// keep cost
$this->values['cost'] = $cost;
// return no change
return [];
}
// last check make sure the payment is more than the cost
if ($payment <= $cost)
{
// show a warning message
$this->enqueueMessage('Add a higher payment received value, that is more than the cost value', 'warning');
// keep cost
$this->values['cost'] = $cost;
// return no change
return [];
}
// good we have both values to lets calculate
return ['cost' => $cost, 'payment' => $payment, 'result' => $this->calculateChange($cost, $payment)];
}
/**
* Get already submitted form values
*
* @return array
*/
public function getFormValues(): array
{
return $this->values;
}
/**
* Enqueue a system message.
*
* @param string $message The message to enqueue.
* @param string $type The message type. Default is message.
*
* @return void
*
* @since 1.0.0
*/
public function enqueueMessage(string $message, string $type = self::MSG_INFO)
{
// Don't add empty messages.
if (empty($message) || trim($message) === '')
{
return;
}
if (!\in_array($message, $this->messages))
{
// Enqueue the message.
$this->messages[] = ['type' => $type, 'message' => $message];
}
}
/**
* Get the message queue.
*
* @return array The system message queue.
*
* @since 1.0.0
*/
public function getMessageQueue(): array
{
// Get messages
return $this->messages;
}
/**
* Do calculation of the change
*
* @return array The change breakdown
*
* @since 1.0.0
*/
private function calculateChange(float $cost, float $payment): array
{
// the denomination breakdown to pennies
$denominations = [
(object) ['names' => '$100 bills', 'name' => '$100 bill', 'value' => '100.00', 'pennies' => 10000],
(object) ['names' => '$50 bills', 'name' => '$50 bill', 'value' => '50.00', 'pennies' => 5000],
(object) ['names' => '$20 bills', 'name' => '$20 bill', 'value' => '20.00', 'pennies' => 2000],
(object) ['names' => '$10 bills', 'name' => '$10 bill', 'value' => '10.00', 'pennies' => 1000],
(object) ['names' => '$5 bills', 'name' => '$5 bill', 'value' => '5.00', 'pennies' => 500],
(object) ['names' => '$1 bills', 'name' => '$1 bill', 'value' => '1.00', 'pennies' => 100],
(object) ['names' => 'quarters', 'name' => 'quarter', 'value' => '0.25', 'pennies' => 25],
(object) ['names' => 'dimes', 'name' => 'dime', 'value' => '0.10', 'pennies' => 10],
(object) ['names' => 'nickles', 'name' => 'nickle', 'value' => '0.05', 'pennies' => 5],
(object) ['names' => 'pennies', 'name' => 'penny', 'value' => '0.01', 'pennies' => 1]
];
// the current change
$change = $this->bc('sub', $payment, $cost, 2);
// convert to pennies
$pennies = $this->bc('mul', $change, 100);
// the breakdown
$breakdown = [];
// work out the number of pennies per denomination
foreach ($denominations as $denomination)
{
if ($pennies >= $denomination->pennies)
{
// get the number of times this denomination goes into the change
$number_of = floor($this->bc('div', $pennies, $denomination->pennies, 2));
// get the number of pennies to deduct from total pennies remaining
$deduction = $this->bc('mul', $denomination->pennies, $number_of);
// make the deduction
$pennies = $this->bc('sub', $pennies, $deduction);
// spacer for any
$spacer = ', ';
// spacer for last
if ($pennies < 1)
{
$spacer = ', and ';
}
// spacer for one or first
if (count($breakdown) == 0)
{
$spacer = '';
}
// set the current change of this denomination
$breakdown[] = [
'name' => ($number_of == 1) ? $denomination->name : $denomination->names,
'value' => $denomination->value,
'number' => $number_of,
'total' => $this->bc('mul', $number_of, (float) $denomination->value, 2),
'number_name' => ($number_of == 1) ? 'a' : $this->numberName($number_of),
'spacer' => $spacer
];
}
}
return ['change' => $change, 'breakdown' => $breakdown];
}
/**
* bc math wrapper (very basic not for accounting)
* I wrote this a few years ago for a private project
*
* @param string $type The type bc math
* @param float $val1 The first value
* @param float $val2 The second value
* @param int $scale The scale value
*
* @return bool|string
*
* @since 1.0.0
*/
private function bc(string $type, float $val1, float $val2, int $scale = 0)
{
// build function name
$function = 'bc' . $type;
// use the bcmath function if available
if (function_exists($function))
{
return $function($val1, $val2, $scale);
}
// if function does not exist we use +-*/ operators (fallback - not ideal)
switch ($type)
{
// Multiply two numbers
case 'mul':
return (string) round($val1 * $val2, $scale);
// Divide of two numbers
case 'div':
return (string) round($val1 / $val2, $scale);
// Adding two numbers
case 'add':
return (string) round($val1 + $val2, $scale);
// Subtract one number from the other
case 'sub':
return (string) round($val1 - $val2, $scale);
// Raise an arbitrary precision number to another
case 'pow':
return (string) round(pow($val1, $val2), $scale);
// Compare two arbitrary precision numbers
case 'comp':
return (round($val1, 2) == round($val2, 2));
}
return false;
}
/**
* Convert an integer into an English word string
* Thanks to Tom Nicholson <http://php.net/manual/en/function.strval.php#41988>
*
* @input int
* @returns string
*
* @since 1.0.0
*/
private function numberName($x)
{
$nwords = array("zero", "one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
"nineteen", "twenty", 30 => "thirty", 40 => "forty",
50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty",
90 => "ninety");
if (!is_numeric($x))
{
$w = $x;
}
elseif (fmod($x, 1) != 0)
{
$w = $x;
}
else
{
if ($x < 0)
{
$w = 'minus ';
$x = -$x;
}
else
{
$w = '';
// ... now $x is a non-negative integer.
}
if ($x < 21) // 0 to 20
{
$w .= $nwords[$x];
}
elseif ($x < 100) // 21 to 99
{
$w .= $nwords[10 * floor($x / 10)];
$r = fmod($x, 10);
if ($r > 0)
{
$w .= ' ' . $nwords[$r];
}
}
elseif ($x < 1000) // 100 to 999
{
$w .= $nwords[floor($x / 100)] . ' hundred';
$r = fmod($x, 100);
if ($r > 0)
{
$w .= ' and ' . $this->numberName($r);
}
}
elseif ($x < 1000000) // 1000 to 999999
{
$w .= $this->numberName(floor($x / 1000)) . ' thousand';
$r = fmod($x, 1000);
if ($r > 0)
{
$w .= ' ';
if ($r < 100)
{
$w .= 'and ';
}
$w .= $this->numberName($r);
}
}
else // millions
{
$w .= $this->numberName(floor($x / 1000000)) . ' million';
$r = fmod($x, 1000000);
if ($r > 0)
{
$w .= ' ';
if ($r < 100)
{
$w .= 'and ';
}
$w .= $this->numberName($r);
}
}
}
return $w;
}
}

View File

@ -1,229 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Model;
use Exception;
use Joomla\Database\DatabaseDriver;
use Joomla\Database\ParameterType;
use Joomla\Model\DatabaseModelInterface;
use Joomla\Model\DatabaseModelTrait;
use RuntimeException;
use stdClass;
/**
* Model class for items
*/
class EditModel implements DatabaseModelInterface
{
use DatabaseModelTrait;
const MSG_INFO = 'info';
/**
* @var array
*/
public $tempItem;
/**
* @var array
*/
private $messages = [];
/**
* Instantiate the model.
*
* @param DatabaseDriver $db The database adapter.
*/
public function __construct(DatabaseDriver $db)
{
$this->setDb($db);
}
/**
* Add an item
*
* @param int $id
* @param string $name
* @param int $age
* @param string $sport
*
* @return int
* @throws Exception
*/
public function setItem(
int $id,
string $name,
int $age,
string $sport): int
{
$db = $this->getDb();
$data = [
'name' => (string) $name,
'age' => (int) $age,
'sport' => (string) $sport
];
// if we have ID update
if ($id > 0)
{
$data['id'] = (int) $id;
// change to object
$data = (object) $data;
try
{
$db->updateObject('#__sportstars', $data, 'id');
}
catch (RuntimeException $exception)
{
throw new RuntimeException($exception->getMessage(), 404);
}
return $id;
}
else
{
// change to object
$data = (object) $data;
try
{
$db->insertObject('#__sportstars', $data);
}
catch (RuntimeException $exception)
{
throw new RuntimeException($exception->getMessage(), 404);
}
return $db->insertid();
}
}
/**
* Get an item
*
* @param int|null $id
*
* @return stdClass
* @throws Exception
*/
public function getItem(?int $id): stdClass
{
$db = $this->getDb();
// default object (use posted values if set)
if (is_array($this->tempItem))
{
$default = (object) $this->tempItem;
}
else
{
$default = new \stdClass();
}
// to be sure ;)
$default->post_key = "?task=create";
// we return the default if id not correct
if (!is_numeric($id))
{
return $default;
}
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__sportstars'))
->where($db->quoteName('id') . ' = :id')
->bind(':id', $id, ParameterType::INTEGER)
->setLimit(1);
try
{
$result = $db->setQuery($query)->loadObject();
}
catch (RuntimeException $e)
{
// we ignore this and just return an empty object
}
if (isset($result) && $result instanceof stdClass)
{
$result->post_key = "?id=$id&task=edit";
return $result;
}
return $default;
}
/**
* @param int $id
*
* @return bool
*/
public function delete(int $id): bool
{
$db = $this->getDb();
// Purge the session
$query = $db->getQuery(true)
->delete($db->quoteName('#__sportstars'))
->where($db->quoteName('id') . ' = :id')
->bind(':id', $id, ParameterType::INTEGER);
try
{
$db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
// delete failed
return false;
}
return true;
}
/**
* Enqueue a system message.
*
* @param string $message The message to enqueue.
* @param string $type The message type. Default is message.
*
* @return void
*
* @since 1.0.0
*/
public function enqueueMessage(string $message, string $type = self::MSG_INFO)
{
// Don't add empty messages.
if (empty($message) || trim($message) === '')
{
return;
}
if (!\in_array($message, $this->messages))
{
// Enqueue the message.
$this->messages[] = ['type' => $type, 'message' => $message];
}
}
/**
* Get the message queue.
*
* @return array The system message queue.
*
* @since 1.0.0
*/
public function getMessageQueue(): array
{
// Get messages
return $this->messages;
}
}

View File

@ -1,50 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Model;
use Joomla\Database\DatabaseDriver;
use Joomla\Model\DatabaseModelInterface;
use Joomla\Model\DatabaseModelTrait;
/**
* Model class for items
*/
class TableModel implements DatabaseModelInterface
{
use DatabaseModelTrait;
/**
* Instantiate the model.
*
* @param DatabaseDriver $db The database adapter.
*/
public function __construct(DatabaseDriver $db)
{
$this->setDb($db);
}
/**
* Get the table values sportstars
*
* @return array
*
*/
public function getTable(): array
{
$db = $this->getDb();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__sportstars'));
return $db->setQuery($query)->loadObjectList('id');
}
}

View File

@ -6,7 +6,7 @@
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Renderer;
namespace Change\Calculator\Renderer;
use Joomla\Application\AbstractApplication;
use Joomla\Application\AbstractWebApplication;

View File

@ -6,7 +6,7 @@
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Renderer;
namespace Change\Calculator\Renderer;
use Symfony\Component\Asset\Packages;
use Twig\Extension\AbstractExtension;
@ -24,11 +24,11 @@ class FrameworkExtension extends AbstractExtension
*
* @return TwigFilter[] An array of TwigFilter instances
*/
public function getFilters()
public function getFilters(): array
{
return [
new TwigFilter('get_class', 'get_class'),
new TwigFilter('strip_root_path', [$this, 'stripRootPath']),
new TwigFilter('strip_root_path', [$this, 'stripRootPath'])
];
}
@ -37,14 +37,13 @@ class FrameworkExtension extends AbstractExtension
*
* @return TwigFunction[] An array of TwigFunction instances
*/
public function getFunctions()
public function getFunctions(): array
{
return [
new TwigFunction('asset', [Packages::class, 'getUrl']),
new TwigFunction('preload', [FrameworkTwigRuntime::class, 'preloadAsset']),
new TwigFunction('request_uri', [FrameworkTwigRuntime::class, 'getRequestUri']),
new TwigFunction('route', [FrameworkTwigRuntime::class, 'getRouteUri']),
new TwigFunction('sri', [FrameworkTwigRuntime::class, 'getSriAttributes'], ['is_safe' => ['html']]),
new TwigFunction('message_queue', [FrameworkTwigRuntime::class, 'getMessageQueue']),
new TwigFunction('shorten_string', [FrameworkTwigRuntime::class, 'shortenString']),
];

View File

@ -6,12 +6,11 @@
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Renderer;
namespace Change\Calculator\Renderer;
use InvalidArgumentException;
use Joomla\Application\AbstractApplication;
use Joomla\Preload\PreloadManager;
use RuntimeException;
/**
* Twig runtime class
@ -33,32 +32,16 @@ class FrameworkTwigRuntime
*/
private $preloadManager;
/**
* The SRI manifest data
*
* @var array|null
*/
private $sriManifestData;
/**
* The path to the SRI manifest data
*
* @var string
*/
private $sriManifestPath;
/**
* Constructor
*
* @param AbstractApplication $app The application object
* @param PreloadManager $preloadManager The HTTP/2 preload manager
* @param string $sriManifestPath The path to the SRI manifest data
*/
public function __construct(AbstractApplication $app, PreloadManager $preloadManager, string $sriManifestPath)
public function __construct(AbstractApplication $app, PreloadManager $preloadManager)
{
$this->app = $app;
$this->preloadManager = $preloadManager;
$this->sriManifestPath = $sriManifestPath;
}
/**
@ -108,7 +91,6 @@ class FrameworkTwigRuntime
{
if (is_string($string) && strlen($string) > $length)
{
$initial = strlen($string);
$words = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
$words_count = count((array)$words);
@ -143,54 +125,6 @@ class FrameworkTwigRuntime
return [];
}
/**
* Get the SRI attributes for an asset
*
* @param string $path A public path
*
* @return string
*/
public function getSriAttributes(string $path): string
{
if ($this->sriManifestData === null)
{
if (!file_exists($this->sriManifestPath))
{
throw new RuntimeException(sprintf('SRI manifest file "%s" does not exist.', $this->sriManifestPath));
}
$sriManifestContents = file_get_contents($this->sriManifestPath);
if ($sriManifestContents === false)
{
throw new RuntimeException(sprintf('Could not read SRI manifest file "%s".', $this->sriManifestPath));
}
$this->sriManifestData = json_decode($sriManifestContents, true);
if (0 < json_last_error())
{
throw new RuntimeException(sprintf('Error parsing JSON from SRI manifest file "%s" - %s', $this->sriManifestPath, json_last_error_msg()));
}
}
$assetKey = "/$path";
if (!isset($this->sriManifestData[$assetKey]))
{
return '';
}
$attributes = '';
foreach ($this->sriManifestData[$assetKey] as $key => $value)
{
$attributes .= ' ' . $key . '="' . $value . '"';
}
return $attributes;
}
/**
* Preload a resource
*

View File

@ -1,14 +1,14 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\Application\AbstractWebApplication;
use Joomla\Application\Controller\ControllerResolverInterface;
@ -17,7 +17,7 @@ use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Sport\Stars\Application\SportStarsApplication;
use Change\Calculator\Application\ChangeCalculatorApplication;
use Joomla\Input\Input;
use Joomla\Router\RouterInterface;
@ -43,8 +43,8 @@ class ApplicationProvider implements ServiceProviderInterface
*/
// This service cannot be protected as it is decorated when the debug bar is available
$container->alias(SportStarsApplication::class, AbstractWebApplication::class)
->share(AbstractWebApplication::class, [$this, 'getSportStarsApplicationClassService']);
$container->alias(ChangeCalculatorApplication::class, AbstractWebApplication::class)
->share(AbstractWebApplication::class, [$this, 'getChangeCalculatorApplicationClassService']);
/*
* Application Helpers and Dependencies
@ -57,16 +57,14 @@ class ApplicationProvider implements ServiceProviderInterface
*
* @param Container $container The DI container.
*
* @return SportStarsApplication
* @return ChangeCalculatorApplication
*/
public function getSportStarsApplicationClassService(Container $container): SportStarsApplication
public function getChangeCalculatorApplicationClassService(Container $container): ChangeCalculatorApplication
{
/** @var SportStarsApplication $application */
$application = new SportStarsApplication(
$application = new ChangeCalculatorApplication(
$container->get(ControllerResolverInterface::class),
$container->get(RouterInterface::class),
$container->get(Input::class),
$container->get('config'),
$container->get(WebClient::class)
);

View File

@ -1,79 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Registry\Registry;
use LConfig;
use RuntimeException;
class ConfigurationProvider implements ServiceProviderInterface
{
/**
* Configuration instance
*
* @var Registry
*/
private $config;
/**
* Constructor.
*
* @param string $file Path to the config file.
*
* @throws RuntimeException
*/
public function __construct(string $file)
{
// Verify the configuration exists and is readable.
if (!is_readable($file))
{
throw new RuntimeException('Configuration file does not exist or is unreadable.');
}
// load the class
include_once $file;
$this->config = new Registry(new LConfig());
// Set database values based on config values
$this->config->loadObject( (object) [
'database' => [
'driver' => $this->config->get('dbtype'),
'host' => $this->config->get('host'),
'port' => $this->config->get('port', ''),
'user' => $this->config->get('user'),
'password' => $this->config->get('password'),
'database' => $this->config->get('db'),
'prefix' => $this->config->get('dbprefix')
]
]);
}
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*/
public function register(Container $container): void
{
$container->share(
'config',
function (): Registry
{
return $this->config;
},
true
);
}
}

View File

@ -1,18 +1,18 @@
<?php
/**
* Joomla! Framework Website
*
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
* Joomla! Framework Website
*
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\Dispatcher;
use Joomla\Event\DispatcherInterface;
use Sport\Stars\EventListener\ErrorSubscriber;
use Change\Calculator\EventListener\ErrorSubscriber;
use Joomla\Renderer\RendererInterface;
use Psr\Log\LoggerInterface;

View File

@ -6,7 +6,7 @@
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;

View File

@ -1,14 +1,14 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;

View File

@ -6,11 +6,10 @@
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Registry\Registry;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Monolog\Processor\PsrLogMessageProcessor;
@ -59,10 +58,7 @@ class LoggingProvider implements ServiceProviderInterface
*/
public function getMonologHandlerApplicationService(Container $container): StreamHandler
{
/** @var Registry $config */
$config = $container->get('config');
$level = strtoupper($config->get('log.application', $config->get('log.level', 'error')));
$level = 'ERROR';
return new StreamHandler(LPATH_ROOT . '/logs/framework.log', constant('\\Monolog\\Logger::' . $level));
}

View File

@ -1,29 +1,25 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\Application\Controller\ContainerControllerResolver;
use Joomla\Application\Controller\ControllerResolverInterface;
use Joomla\Database\DatabaseInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Sport\Stars\Controller\TableController;
use Sport\Stars\Controller\EditController;
use Sport\Stars\Controller\WrongCmsController;
use Sport\Stars\Model\TableModel;
use Sport\Stars\Model\EditModel;
use Sport\Stars\View\TableHtmlView;
use Sport\Stars\View\EditHtmlView;
use Sport\Stars\Application\SportStarsApplication;
use Change\Calculator\Controller\CalculatorController;
use Change\Calculator\Controller\WrongCmsController;
use Change\Calculator\Model\CalculatorModel;
use Change\Calculator\View\CalculatorHtmlView;
use Change\Calculator\Application\ChangeCalculatorApplication;
use Joomla\Input\Input;
@ -46,28 +42,19 @@ class MVCProvider implements ServiceProviderInterface
->share(ControllerResolverInterface::class, [$this, 'getControllerResolverService']);
// Controllers
$container->alias(TableController::class, 'controller.table')
->share('controller.table', [$this, 'getControllerTableService'], true);
$container->alias(EditController::class, 'controller.edit')
->share('controller.edit', [$this, 'getControllerEditService'], true);
$container->alias(CalculatorController::class, 'controller.calculator')
->share('controller.calculator', [$this, 'getControllerCalculatorService'], true);
$container->alias(WrongCmsController::class, 'controller.wrong.cms')
->share('controller.wrong.cms', [$this, 'getControllerWrongCmsService'], true);
// Models
$container->alias(TableModel::class, 'model.table')
->share('model.table', [$this, 'getModelTableService'], true);
$container->alias(EditModel::class, 'model.edit')
->share('model.edit', [$this, 'getModelEditService'], true);
$container->alias(CalculatorModel::class, 'model.calculator')
->share('model.calculator', [$this, 'getModelCalculatorService'], true);
// Views
$container->alias(TableHtmlView::class, 'view.table.html')
->share('view.table.html', [$this, 'getViewTableHtmlService'], true);
$container->alias(EditHtmlView::class, 'view.edit.html')
->share('view.edit.html', [$this, 'getViewEditHtmlService'], true);
$container->alias(CalculatorHtmlView::class, 'view.calculator.html')
->share('view.calculator.html', [$this, 'getViewCalculatorHtmlService'], true);
}
/**
@ -93,102 +80,53 @@ class MVCProvider implements ServiceProviderInterface
{
return new WrongCmsController(
$container->get(Input::class),
$container->get(SportStarsApplication::class)
$container->get(ChangeCalculatorApplication::class)
);
}
/**
* Get the `controller.table` service
* Get the `controller.calculator` service
*
* @param Container $container The DI container.
*
* @return TableController
* @return CalculatorController
*/
public function getControllerTableService(Container $container): TableController
public function getControllerCalculatorService(Container $container): CalculatorController
{
return new TableController(
$container->get(TableHtmlView::class),
return new CalculatorController(
$container->get(CalculatorHtmlView::class),
$container->get(Input::class),
$container->get(SportStarsApplication::class)
$container->get(ChangeCalculatorApplication::class)
);
}
/**
* Get the `controller.edit` service
* Get the `model.calculator` service
*
* @param Container $container The DI container.
*
* @return EditController
* @return CalculatorModel
*/
public function getControllerEditService(Container $container): EditController
public function getModelCalculatorService(Container $container): CalculatorModel
{
return new EditController(
$container->get(EditModel::class),
$container->get(EditHtmlView::class),
$container->get(Input::class),
$container->get(SportStarsApplication::class)
);
return new CalculatorModel();
}
/**
* Get the `model.table` service
* Get the `view.calculator.html` service
*
* @param Container $container The DI container.
*
* @return TableModel
* @return CalculatorHtmlView
*/
public function getModelTableService(Container $container): TableModel
public function getViewCalculatorHtmlService(Container $container): CalculatorHtmlView
{
return new TableModel($container->get(DatabaseInterface::class));
}
/**
* Get the `model.edit` service
*
* @param Container $container The DI container.
*
* @return EditModel
*/
public function getModelEditService(Container $container): EditModel
{
return new EditModel($container->get(DatabaseInterface::class));
}
/**
* Get the `view.table.html` service
*
* @param Container $container The DI container.
*
* @return TableHtmlView
*/
public function getViewTableHtmlService(Container $container): TableHtmlView
{
$view = new TableHtmlView(
$container->get('model.edit'),
$container->get('model.table'),
$view = new CalculatorHtmlView(
$container->get('model.calculator'),
$container->get('renderer')
);
$view->setLayout('table.twig');
return $view;
}
/**
* Get the `view.edit.html` service
*
* @param Container $container The DI container.
*
* @return EditHtmlView
*/
public function getViewEditHtmlService(Container $container): EditHtmlView
{
$view = new EditHtmlView(
$container->get('model.edit'),
$container->get('renderer')
);
$view->setLayout('edit.twig');
$view->setLayout('calculator.twig');
return $view;
}

View File

@ -1,20 +1,19 @@
<?php
/**
* @package Sport Stars
* @package Change Calculator
*
* @created 19th April 2022
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Sport\Stars\Controller\TableController;
use Sport\Stars\Controller\EditController;
use Change\Calculator\Controller\CalculatorController;
use Joomla\Router\Router;
use Joomla\Router\RouterInterface;
@ -52,15 +51,11 @@ class RouterProvider implements ServiceProviderInterface
$router = new Router;
/**
* Sports Stars
* Change Calculator
**/
$router->get(
'/',
TableController::class
);
$router->all(
'/edit',
EditController::class
'/',
CalculatorController::class
);
return $router;

View File

@ -6,40 +6,23 @@
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
*/
namespace Sport\Stars\Service;
namespace Change\Calculator\Service;
use Joomla\Application\AbstractApplication;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Registry\Registry;
use Sport\Stars\Asset\MixPathPackage;
use Sport\Stars\Renderer\ApplicationContext;
use Sport\Stars\Renderer\FrameworkExtension;
use Sport\Stars\Renderer\FrameworkTwigRuntime;
use Change\Calculator\Renderer\FrameworkExtension;
use Change\Calculator\Renderer\FrameworkTwigRuntime;
use Joomla\Preload\PreloadManager;
use Joomla\Renderer\RendererInterface;
use Joomla\Renderer\TwigRenderer;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Asset\PathPackage;
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
use Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy;
use Twig\Cache\CacheInterface;
use Twig\Cache\FilesystemCache;
use Twig\Cache\NullCache;
use Twig\Environment;
use Twig\Extension\DebugExtension;
use Twig\Extension\ProfilerExtension;
use Twig\Extra\Intl\IntlExtension;
use Twig\Loader\FilesystemLoader;
use Twig\Loader\LoaderInterface;
use Twig\Profiler\Profile;
use Twig\RuntimeLoader\ContainerRuntimeLoader;
use Twig_CacheInterface;
use Twig_ContainerRuntimeLoader;
use Twig_Environment;
use Twig_Extension_Debug;
use Twig_Extension_Profiler;
use Twig_LoaderInterface;
use Twig_Profiler_Profile;
/**
* Templating service provider
@ -56,84 +39,34 @@ class TemplatingProvider implements ServiceProviderInterface
*/
public function register(Container $container): void
{
$container->alias(Packages::class, 'asset.packages')
->share('asset.packages', [$this, 'getAssetPackagesService'], true);
$container->alias(RendererInterface::class, 'renderer')
->alias(TwigRenderer::class, 'renderer')
->share('renderer', [$this, 'getRendererService'], true);
$container->alias(CacheInterface::class, 'twig.cache')
->alias(Twig_CacheInterface::class, 'twig.cache')
->share('twig.cache', [$this, 'getTwigCacheService'], true);
$container->alias(Environment::class, 'twig.environment')
->alias(Twig_Environment::class, 'twig.environment')
->share('twig.environment', [$this, 'getTwigEnvironmentService'], true);
$container->alias(DebugExtension::class, 'twig.extension.debug')
->alias(Twig_Extension_Debug::class, 'twig.extension.debug')
->share('twig.extension.debug', [$this, 'getTwigExtensionDebugService'], true);
$container->alias(FrameworkExtension::class, 'twig.extension.framework')
->share('twig.extension.framework', [$this, 'getTwigExtensionFrameworkService'], true);
// This service cannot be protected as it is decorated when the debug bar is available
$container->alias(ProfilerExtension::class, 'twig.extension.profiler')
->alias(Twig_Extension_Profiler::class, 'twig.extension.profiler')
->share('twig.extension.profiler', [$this, 'getTwigExtensionProfilerService']);
$container->alias(LoaderInterface::class, 'twig.loader')
->alias(Twig_LoaderInterface::class, 'twig.loader')
->share('twig.loader', [$this, 'getTwigLoaderService'], true);
$container->alias(Profile::class, 'twig.profiler.profile')
->alias(Twig_Profiler_Profile::class, 'twig.profiler.profile')
->share('twig.profiler.profile', [$this, 'getTwigProfilerProfileService'], true);
$container->alias(FrameworkTwigRuntime::class, 'twig.runtime.framework')
->share('twig.runtime.framework', [$this, 'getTwigRuntimeFrameworkService'], true);
$container->alias(ContainerRuntimeLoader::class, 'twig.runtime.loader')
->alias(Twig_ContainerRuntimeLoader::class, 'twig.runtime.loader')
->share('twig.runtime.loader', [$this, 'getTwigRuntimeLoaderService'], true);
$this->tagTwigExtensions($container);
}
/**
* Get the `asset.packages` service
*
* @param Container $container The DI container.
*
* @return Packages
*/
public function getAssetPackagesService(Container $container): Packages
{
/** @var AbstractApplication $app */
$app = $container->get(AbstractApplication::class);
$context = new ApplicationContext($app);
$mediaPath = $app->get('uri.media.path', '/media/');
$defaultPackage = new PathPackage($mediaPath, new EmptyVersionStrategy, $context);
$mixStrategy = new MixPathPackage(
$defaultPackage,
$mediaPath,
new JsonManifestVersionStrategy(LPATH_ROOT . '/media/mix-manifest.json'),
$context
);
return new Packages(
$defaultPackage,
[
'mix' => $mixStrategy,
]
);
}
/**
* Get the `renderer` service
*
@ -146,31 +79,6 @@ class TemplatingProvider implements ServiceProviderInterface
return new TwigRenderer($container->get('twig.environment'));
}
/**
* Get the `twig.cache` service
*
* @param Container $container The DI container.
*
* @return Twig_CacheInterface
*/
public function getTwigCacheService(Container $container): Twig_CacheInterface
{
/** @var Registry $config */
$config = $container->get('config');
// Pull down the renderer config
$cacheEnabled = $config->get('template.cache.enabled', false);
$cachePath = $config->get('template.cache.path', 'cache/twig');
$debug = $config->get('template.debug', false);
if ($debug === false && $cacheEnabled !== false)
{
return new FilesystemCache(LPATH_ROOT . '/' . $cachePath);
}
return new NullCache;
}
/**
* Get the `twig.environment` service
*
@ -180,10 +88,7 @@ class TemplatingProvider implements ServiceProviderInterface
*/
public function getTwigEnvironmentService(Container $container): Environment
{
/** @var Registry $config */
$config = $container->get('config');
$debug = $config->get('template.debug', false);
$debug = false;
$environment = new Environment(
$container->get('twig.loader'),
@ -193,14 +98,14 @@ class TemplatingProvider implements ServiceProviderInterface
// Add the runtime loader
$environment->addRuntimeLoader($container->get('twig.runtime.loader'));
// Set up the environment's caching service
$environment->setCache($container->get('twig.cache'));
// Add the Twig extensions
$environment->setExtensions($container->getTagged('twig.extension'));
// add international
$environment->addExtension(new IntlExtension());
// Add a global tracking the debug states
$environment->addGlobal('appDebug', $config->get('debug', false));
$environment->addGlobal('appDebug', false);
$environment->addGlobal('fwDebug', $debug);
return $environment;
@ -230,26 +135,14 @@ class TemplatingProvider implements ServiceProviderInterface
return new FrameworkExtension;
}
/**
* Get the `twig.extension.profiler` service
*
* @param Container $container The DI container.
*
* @return ProfilerExtension
*/
public function getTwigExtensionProfilerService(Container $container): ProfilerExtension
{
return new ProfilerExtension($container->get('twig.profiler.profile'));
}
/**
* Get the `twig.loader` service
*
* @param Container $container The DI container.
*
* @return Twig_LoaderInterface
* @return FilesystemLoader
*/
public function getTwigLoaderService(Container $container): Twig_LoaderInterface
public function getTwigLoaderService(Container $container): FilesystemLoader
{
return new FilesystemLoader([LPATH_TEMPLATES]);
}
@ -277,8 +170,7 @@ class TemplatingProvider implements ServiceProviderInterface
{
return new FrameworkTwigRuntime(
$container->get(AbstractApplication::class),
$container->get(PreloadManager::class),
LPATH_ROOT . '/media/sri-manifest.json'
$container->get(PreloadManager::class)
);
}
@ -303,18 +195,6 @@ class TemplatingProvider implements ServiceProviderInterface
*/
private function tagTwigExtensions(Container $container): void
{
/** @var Registry $config */
$config = $container->get('config');
$debug = $config->get('template.debug', false);
$twigExtensions = ['twig.extension.framework'];
if ($debug)
{
$twigExtensions[] = 'twig.extension.debug';
}
$container->tag('twig.extension', $twigExtensions);
$container->tag('twig.extension', ['twig.extension.framework']);
}
}

View File

@ -1,260 +0,0 @@
<?php
/**
* Joomla! Content Management System
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\String;
use Algo26\IdnaConvert\ToIdn;
use Algo26\IdnaConvert\ToUnicode;
use Joomla\Uri\UriHelper;
/**
* Joomla Platform String Punycode Class
*
* Class for handling UTF-8 URLs
* Wraps the Punycode library
* All functions assume the validity of utf-8 URLs.
*
* @since 3.1.2
*/
abstract class PunycodeHelper
{
/**
* Transforms a UTF-8 string to a Punycode string
*
* @param string $utfString The UTF-8 string to transform
*
* @return string The punycode string
*
* @since 3.1.2
*/
public static function toPunycode($utfString)
{
return (new ToIdn)->convert($utfString);
}
/**
* Transforms a Punycode string to a UTF-8 string
*
* @param string $punycodeString The Punycode string to transform
*
* @return string The UF-8 URL
*
* @since 3.1.2
*/
public static function fromPunycode($punycodeString)
{
return (new ToUnicode)->convert($punycodeString);
}
/**
* Transforms a UTF-8 URL to a Punycode URL
*
* @param string $uri The UTF-8 URL to transform
*
* @return string The punycode URL
*
* @since 3.1.2
*/
public static function urlToPunycode($uri)
{
$parsed = UriHelper::parse_url($uri);
if (!isset($parsed['host']) || $parsed['host'] == '')
{
// If there is no host we do not need to convert it.
return $uri;
}
$host = $parsed['host'];
$hostExploded = explode('.', $host);
$newhost = '';
foreach ($hostExploded as $hostex)
{
$hostex = static::toPunycode($hostex);
$newhost .= $hostex . '.';
}
$newhost = substr($newhost, 0, -1);
$newuri = '';
if (!empty($parsed['scheme']))
{
// Assume :// is required although it is not always.
$newuri .= $parsed['scheme'] . '://';
}
if (!empty($newhost))
{
$newuri .= $newhost;
}
if (!empty($parsed['port']))
{
$newuri .= ':' . $parsed['port'];
}
if (!empty($parsed['path']))
{
$newuri .= $parsed['path'];
}
if (!empty($parsed['query']))
{
$newuri .= '?' . $parsed['query'];
}
if (!empty($parsed['fragment']))
{
$newuri .= '#' . $parsed['fragment'];
}
return $newuri;
}
/**
* Transforms a Punycode URL to a UTF-8 URL
*
* @param string $uri The Punycode URL to transform
*
* @return string The UTF-8 URL
*
* @since 3.1.2
*/
public static function urlToUTF8($uri)
{
if (empty($uri))
{
return '';
}
$parsed = UriHelper::parse_url($uri);
if (!isset($parsed['host']) || $parsed['host'] == '')
{
// If there is no host we do not need to convert it.
return $uri;
}
$host = $parsed['host'];
$hostExploded = explode('.', $host);
$newhost = '';
foreach ($hostExploded as $hostex)
{
$hostex = self::fromPunycode($hostex);
$newhost .= $hostex . '.';
}
$newhost = substr($newhost, 0, -1);
$newuri = '';
if (!empty($parsed['scheme']))
{
// Assume :// is required although it is not always.
$newuri .= $parsed['scheme'] . '://';
}
if (!empty($newhost))
{
$newuri .= $newhost;
}
if (!empty($parsed['port']))
{
$newuri .= ':' . $parsed['port'];
}
if (!empty($parsed['path']))
{
$newuri .= $parsed['path'];
}
if (!empty($parsed['query']))
{
$newuri .= '?' . $parsed['query'];
}
if (!empty($parsed['fragment']))
{
$newuri .= '#' . $parsed['fragment'];
}
return $newuri;
}
/**
* Transforms a UTF-8 email to a Punycode email
* This assumes a valid email address
*
* @param string $email The UTF-8 email to transform
*
* @return string The punycode email
*
* @since 3.1.2
*/
public static function emailToPunycode($email)
{
$explodedAddress = explode('@', $email);
// Not addressing UTF-8 user names
$newEmail = $explodedAddress[0];
if (!empty($explodedAddress[1]))
{
$domainExploded = explode('.', $explodedAddress[1]);
$newdomain = '';
foreach ($domainExploded as $domainex)
{
$domainex = static::toPunycode($domainex);
$newdomain .= $domainex . '.';
}
$newdomain = substr($newdomain, 0, -1);
$newEmail = $newEmail . '@' . $newdomain;
}
return $newEmail;
}
/**
* Transforms a Punycode email to a UTF-8 email
* This assumes a valid email address
*
* @param string $email The punycode email to transform
*
* @return string The punycode email
*
* @since 3.1.2
*/
public static function emailToUTF8($email)
{
$explodedAddress = explode('@', $email);
// Not addressing UTF-8 user names
$newEmail = $explodedAddress[0];
if (!empty($explodedAddress[1]))
{
$domainExploded = explode('.', $explodedAddress[1]);
$newdomain = '';
foreach ($domainExploded as $domainex)
{
$domainex = static::fromPunycode($domainex);
$newdomain .= $domainex . '.';
}
$newdomain = substr($newdomain, 0, -1);
$newEmail = $newEmail . '@' . $newdomain;
}
return $newEmail;
}
}

View File

@ -0,0 +1,101 @@
<?php
/**
* @package Change Calculator
*
* @created 24th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Change\Calculator\View;
use Change\Calculator\Model\CalculatorModel;
use Joomla\Renderer\RendererInterface;
use Joomla\View\HtmlView;
/**
* Page HTML view class for the application
*/
class CalculatorHtmlView extends HtmlView
{
/**
* The table model object.
*
* @var CalculatorModel
*/
private $model;
/**
* The payment amount
*
* @var float
*/
private $payment;
/**
* The cost amount
*
* @var float
*/
private $cost;
/**
* Instantiate the view.
*
* @param CalculatorModel $model The calculator model object.
* @param RendererInterface $renderer The renderer object.
*/
public function __construct(CalculatorModel $model, RendererInterface $renderer)
{
parent::__construct($renderer);
$this->model = $model;
}
/**
* Method to render the view
*
* @return string The rendered view
*/
public function render(): string
{
// start the data bucket
$data = [];
// only load the change if there is any
$data['change'] = $this->model->getChange($this->cost, $this->payment);
// if we still have from values we load them back
$data['form'] = $this->model->getFormValues();
// add any messages we may have in the model
$data['messages_queue'] = $this->model->getMessageQueue();
// now set the data
$this->setData($data);
return parent::render();
}
/**
* Method to set the cost
*
* @param float $cost The cost amount
*
* @return void
*/
public function setCost(float $cost)
{
$this->cost = $cost;
}
/**
* Method to set the payment
*
* @param float $payment The payment amount
*
* @return void
*/
public function setPayment(float $payment)
{
$this->payment = $payment;
}
}

View File

@ -1,79 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\View;
use Exception;
use Sport\Stars\Model\EditModel;
use Joomla\Renderer\RendererInterface;
use Joomla\View\HtmlView;
/**
* Page HTML view class for the application
*/
class EditHtmlView extends HtmlView
{
/**
* The active item
*
* @var int
*/
private $id = 0;
/**
* The model object.
*
* @var EditModel
*/
private $model;
/**
* Instantiate the view.
*
* @param EditModel $model The page model object.
* @param RendererInterface $renderer The renderer object.
*/
public function __construct(EditModel $model, RendererInterface $renderer)
{
parent::__construct($renderer);
$this->model = $model;
}
/**
* Method to render the view
*
* @return string The rendered view
* @throws Exception
*/
public function render()
{
$this->setData(
[
'form' => $this->model->getItem($this->id),
'messages_queue' => $this->model->getMessageQueue()
]
);
return parent::render();
}
/**
* Set the active item
*
* @param string $id The active item
*
* @return void
*/
public function setActiveItem(int $id): void
{
$this->id = $id;
}
}

View File

@ -1,68 +0,0 @@
<?php
/**
* @package Sport Stars
*
* @created 19th April 2022
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
* @git WEBD-325-45 <https://git.vdm.dev/Llewellyn/WEBD-325-45>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Sport\Stars\View;
use Sport\Stars\Model\EditModel;
use Sport\Stars\Model\TableModel;
use Joomla\Renderer\RendererInterface;
use Joomla\View\HtmlView;
/**
* Page HTML view class for the application
*/
class TableHtmlView extends HtmlView
{
/**
* The edit model object.
*
* @var EditModel
*/
private $model;
/**
* The table model object.
*
* @var TableModel
*/
private $tableModel;
/**
* Instantiate the view.
*
* @param EditModel $model The edit model object.
* @param TableModel $tableModel The table model object.
* @param RendererInterface $renderer The renderer object.
*/
public function __construct(EditModel $model, TableModel $tableModel, RendererInterface $renderer)
{
parent::__construct($renderer);
$this->tableModel = $tableModel;
$this->model = $model;
}
/**
* Method to render the view
*
* @return string The rendered view
*/
public function render()
{
$this->setData(
[
'list' => $this->tableModel->getTable(),
'messages_queue' => $this->model->getMessageQueue()
]
);
return parent::render();
}
}

View File

@ -1,28 +0,0 @@
# If the Joomla site is installed within a folder
# eg www.example.com/joomla/ then the robots.txt file
# MUST be moved to the site root
# eg www.example.com/robots.txt
# AND the joomla folder name MUST be prefixed to all of the
# paths.
# eg the Disallow rule for the /administrator/ folder MUST
# be changed to read
# Disallow: /joomla/administrator/
#
# For more information about the robots.txt standard, see:
# https://www.robotstxt.org/orig.html
User-agent: *
Disallow: /administrator/
Disallow: /bin/
Disallow: /cache/
Disallow: /cli/
Disallow: /components/
Disallow: /includes/
Disallow: /installation/
Disallow: /language/
Disallow: /layouts/
Disallow: /libraries/
Disallow: /logs/
Disallow: /modules/
Disallow: /plugins/
Disallow: /tmp/

View File

@ -1 +0,0 @@
<!DOCTYPE html><title></title>

View File

@ -1,18 +0,0 @@
--
-- DATABASE STRUCTURE FOR SPORT STARS
--
--
-- Table structure for table `homework_sportstars`
--
CREATE TABLE IF NOT EXISTS `homework_sportstars` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT 'The star name.',
`age` int(3) NOT NULL DEFAULT 0 COMMENT 'The star age.',
`sport` varchar(100) NOT NULL COMMENT 'The star sport name.',
PRIMARY KEY (`id`),
KEY `idx_name` (`name`(100)),
KEY `idx_age` (`age`),
KEY `idx_sport` (`sport`(100))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=0;

View File

@ -0,0 +1,79 @@
{% extends "index.twig" %}
{% block title %}Change Calculator{% endblock %}
{% block content %}
<div class="uk-container uk-margin">
<h1 class="uk-article-title">Change Calculator</h1>
{{ block("messages_queue", "message_queue.twig") }}
<form class="uk-form-stacked" action="{{ route() }}" method="post">
<div class="uk-child-width-1-2 uk-margin" uk-grid>
<div>
<label class="uk-form-label">Transaction Cost</label>
<div class="uk-form-controls">
<input name="cost" class="uk-input uk-width-1-1" type="text" placeholder="Add the cost here..." value="{{ form.cost|default('') }}">
</div>
</div>
<div>
<label class="uk-form-label">Payment Received</label>
<div class="uk-form-controls">
<input name="payment" class="uk-input uk-width-1-1" type="text" placeholder="Add the exact amount of money that the customer handed over to pay..." value="{{ form.payment|default('') }}">
</div>
</div>
</div>
<input type="submit" class="uk-button uk-button-primary uk-width-1-1" value="Calculate"/>
</form>
</div>
{% if change %}
<div class="uk-container uk-margin">
<h1 class="uk-article-title">Here is your change</h1>
<div class="uk-alert-success" uk-alert>
<h3>Your last transaction</h3>
<dl class="uk-description-list">
<dt>Cost:</dt>
<dd>{{ change.cost|format_currency('USD') }}</dd>
<dt>Payment:</dt>
<dd>{{ change.payment|format_currency('USD') }}</dd>
{% if change.result.change %}
<dt>Change:</dt>
<dd>{{ change.result.change|format_currency('USD') }}</dd>
{% endif %}
</dl>
{% if change.result.breakdown %}
<p>The cashier should return {{ change.result.change|format_currency('USD') }} to the customer as
{% for denomination in change.result.breakdown %}{{ denomination.spacer }}{{ denomination.number_name }} {{ denomination.name }}{% endfor %}
</p>
{% else %}
There has been an error, please try again.
{% endif %}
</div>
{% if change.result.breakdown %}
<table class="uk-table uk-table-small uk-table-divider uk-table-responsive">
<thead>
<tr>
<th>Denomination</th>
<th class="uk-table-shrink">Number</th>
<th class="uk-table-shrink">Total</th>
</tr>
</thead>
<tbody>
{% for denomination in change.result.breakdown %}
<tr>
<td>{{ denomination.value|format_currency('USD') }}</td>
<td>{{ denomination.number }}</td>
<td>{{ denomination.total|format_currency('USD') }}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td></td>
<td >Total:</td>
<td>{{ change.result.change|format_currency('USD') }}</td>
</tr>
</tfoot>
</table>
{% endif %}
</div>
{% endif %}
{% endblock %}

View File

@ -1,49 +0,0 @@
{% extends "index.twig" %}
{% block title %}Athlete{% endblock %}
{% block content %}
<div class="uk-container uk-margin">
<h1 class="uk-article-title">Athlete</h1>
{{ block("messages_queue", "message_queue.twig") }}
<form class="uk-form-stacked" action="{{ route() }}edit{{ form.post_key|default('') }}" method="post">
<div class="uk-button-group uk-width-1-1 uk-margin">
<input type="submit" class="uk-button uk-button-primary uk-width-1-2" value="Save"/>
<a href="{{ route() }}" type="button" class="uk-button uk-button-danger uk-width-1-2">Close</a>
</div>
<div class="uk-child-width-1-2 uk-margin" uk-grid>
<div>
<label class="uk-form-label">Name</label>
<div class="uk-form-controls">
<input name="name" class="uk-input uk-width-1-1" type="text" placeholder="Add the name here..." value="{{ form.name|default('') }}">
</div>
</div>
<div>
<label class="uk-form-label">Age</label>
<div class="uk-form-controls">
<input name="age" class="uk-input uk-width-1-1" type="text" placeholder="Your age..." value="{{ form.age|default('') }}">
</div>
</div>
</div>
<div>
<label class="uk-form-label">Sport</label>
<div class="uk-form-controls">
<input name="sport" class="uk-input uk-width-1-1" type="text" placeholder="Your sport name..." value="{{ form.sport|default('') }}">
</div>
</div>
<input type="hidden" name="item_id" value="{{ form.id|default(0) }}">
</form>
</div>
<script>
ClassicEditor.create(document.querySelector(`#item-text`), {
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ],
heading: {
options: [
{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' }
]
}
}).catch(error => { console.error(error);});
</script>
{% endblock %}

View File

@ -2,7 +2,7 @@
{% block bodyNavigation %}{% endblock %}
{% block title %}Sport Stars Error{% endblock %}
{% block title %}Change Calculator Error{% endblock %}
{% block content %}
<div class="uk-container uk-margin">
@ -11,7 +11,7 @@
<p class="lead">Sorry, we couldn't find the page matching your request. Try using the navigation to find what you were looking for?</p>
{% else %}
<h2>Ouch, That's an Error</h2>
<p class="lead">Well this is embarrassing, seems there was an error processing this request. Perhaps try again? Or <a href="https://github.com/sportstars/crm/issues/new?title=[FW Site]&body=Please state the nature of your development emergency">file an issue</a> so we can address it.</p>
<p class="lead">Well this is embarrassing, seems there was an error processing this request. Perhaps try again? Or <a href="https://github.com/changecalculator/crm/issues/new?title=[FW Site]&body=Please state the nature of your development emergency">file an issue</a> so we can address it.</p>
{% endif %}
{% if appDebug %}

View File

@ -2,7 +2,7 @@
<div class="uk-section uk-section-primary">
<div class="uk-container uk-container-small">
<div class="uk-text-center uk-card-body">
<small>Copyright © Sport Stars. All Rights Reserved.</small>
<small>Copyright © Change Calculator. All Rights Reserved.</small>
</div>
</div>
</div>

View File

@ -17,18 +17,18 @@
<!-- End for Responsive -->
<!-- For SEO -->
<title>{% block title %}Sport Stars!{% endblock %}</title>
<title>{% block title %}Change Calculator!{% endblock %}</title>
<meta charset="utf-8">
<meta name="description" content="{% block metaDescription %}The Sport Stars!{% endblock %}">
<meta name="generator" content="Sport Stars!" />
<meta name="description" content="{% block metaDescription %}The Change Calculator!{% endblock %}">
<meta name="generator" content="Change Calculator!" />
<meta property="og:description" content="{{ block('metaDescription') }}" />
<meta property="og:locale" content="en_US" />
<meta property="og:site_name" content="Sport Stars!" />
<meta property="og:site_name" content="Change Calculator!" />
<meta property="og:title" content="{{ block('title') }}" />
<meta property="og:type" content="{% block metaOgType %}website{% endblock %}" />
<meta property="og:url" content="{{ request_uri() }}" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@SportStars" />
<meta name="twitter:site" content="@ChangeCalculator" />
<meta name="twitter:description" content="{{ block('metaDescription') }}" />
<meta name="twitter:title" content="{{ block('title') }}" />
{% block metadata %}{% endblock %}

View File

@ -4,7 +4,7 @@
<meta http-equiv="Content-Language" content="en-GB">
<meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sport Stars: Environment Setup Incomplete</title><!-- Sets the page title, IMPORTANT DO NOT REMOVE -->
<title>Change Calculator: Environment Setup Incomplete</title><!-- Sets the page title, IMPORTANT DO NOT REMOVE -->
<style>html{background:#ee2a00;background:radial-gradient(ellipse at center,#f1f1f1 0,#ee2a00 100%);background-attachment:fixed;background-repeat:no-repeat}body{background-color:transparent;color:#555;font:14px/18px sans-serif}body,ol,ul{margin:0;padding:0}ol,ul{list-style:none}a{color:#0084b4;text-decoration:none}a:focus,a:hover{text-decoration:underline}p a{line-height:inherit}.container{align-items:center;display:flex;flex-direction:column;height:100vh;justify-content:center;margin:0 auto;overflow:hidden;position:relative;width:100%}.alert-main{background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:5px;box-shadow:0 0 10px rgba(0,0,0,.05);display:block;margin:0 20px;padding:20px 60px;position:relative}svg{bottom:-120px;position:absolute;right:-70px;-webkit-transform:rotate(10deg);transform:rotate(10deg);width:400px;z-index:-1}h1,p{text-rendering:optimizeLegibility;position:relative;text-align:center;z-index:10}h1{font-size:40px;font-weight:200;line-height:1;margin:18px 0 0;text-shadow:0 1px 2px rgba(0,0,0,.2)}label,p{color:#777;font-size:18px;font-weight:300;line-height:25px;margin:10px 0 20px}p a{color:#1c3d5c;font-weight:700}.link-help{background-color:#f5f5f5;border:1px solid rgba(0,0,0,.1);border-radius:.25rem;font-size:1rem;font-weight:400;padding:.4rem .85rem;text-decoration:none}.link-help:hover{background-color:#eee;text-decoration:none}.footer{font-size:11px;margin:8px 20px;text-align:left}.footer ul{margin-bottom:5px}.footer li{display:inline;line-height:20px;margin:0 5px}.footer a,.footer li{color:#1c3d5c}.footer a:hover{color:#59b0ff}.links{display:block;font-size:1rem;margin-left:auto;margin-right:auto;margin-top:4rem;text-align:center}.links li{display:inline-block;margin-top:20px}@media screen and (max-width:480px){.container{height:auto;padding-bottom:20px;padding-top:20px}h1{font-size:30px}.link-help{white-space:nowrap}}</style><!-- Sets the page styling, IMPORTANT DO NOT REMOVE -->
</head>
<body>
@ -12,19 +12,19 @@
<div class="container-main">
<div class="alert-main">
<h1 id="headerText">Environment Setup Incomplete</h1>
<p><span id="descText1">It looks like you are trying to run Sport Stars! from our git repository. To do so requires you complete a couple of extra steps first.</span></p>
<p><span id="descText1">It looks like you are trying to run Change Calculator! from our git repository. To do so requires you complete a couple of extra steps first.</span></p>
<p style="text-align: left;">
0. Make sure you have <a href="https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos">composer</a> installed on your system.
<br />
1. In your terminal go to the root folder of your Sport Stars website where you will find the <u>composer.json</u> file.
1. In your terminal go to the root folder of your Change Calculator website where you will find the <u>composer.json</u> file.
<br />
2. Run the following command <code>composer install</code> to install all PHP packages.
</p>
</div>
<div class="footer">
<ul class="links">
<li><a href="https://www.sportstars.org/">Sport Stars</a></li> -
<li><a href="https://git.vdm.dev/sportstars/">Help</a></li>
<li><a href="https://www.changecalculator.org/">Change Calculator</a></li> -
<li><a href="https://git.vdm.dev/changecalculator/">Help</a></li>
</ul>
</div>
</div>

View File

@ -4,7 +4,7 @@
<meta http-equiv="Content-Language" content="en-GB">
<meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sport Stars: unsupported PHP version</title><!-- Sets the page title, IMPORTANT DO NOT REMOVE -->
<title>Change Calculator: unsupported PHP version</title><!-- Sets the page title, IMPORTANT DO NOT REMOVE -->
<style>html{background:#ee2a00;background:radial-gradient(ellipse at center,#f1f1f1 0,#ee2a00 100%);background-attachment:fixed;background-repeat:no-repeat}body{background-color:transparent;color:#555;font:14px/18px sans-serif}body,ol,ul{margin:0;padding:0}ol,ul{list-style:none}a{color:#0084b4;text-decoration:none}a:focus,a:hover{text-decoration:underline}p a{line-height:inherit}.container{align-items:center;display:flex;flex-direction:column;height:100vh;justify-content:center;margin:0 auto;overflow:hidden;position:relative;width:100%}.alert-main{background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:5px;box-shadow:0 0 10px rgba(0,0,0,.05);display:block;margin:0 20px;padding:20px 60px;position:relative}svg{bottom:-120px;position:absolute;right:-70px;-webkit-transform:rotate(10deg);transform:rotate(10deg);width:400px;z-index:-1}h1,p{text-rendering:optimizeLegibility;position:relative;text-align:center;z-index:10}h1{font-size:40px;font-weight:200;line-height:1;margin:18px 0 0;text-shadow:0 1px 2px rgba(0,0,0,.2)}label,p{color:#777;font-size:18px;font-weight:300;line-height:25px;margin:10px 0 20px}p a{color:#1c3d5c;font-weight:700}.link-help{background-color:#f5f5f5;border:1px solid rgba(0,0,0,.1);border-radius:.25rem;font-size:1rem;font-weight:400;padding:.4rem .85rem;text-decoration:none}.link-help:hover{background-color:#eee;text-decoration:none}.footer{font-size:11px;margin:8px 20px;text-align:left}.footer ul{margin-bottom:5px}.footer li{display:inline;line-height:20px;margin:0 5px}.footer a,.footer li{color:#1c3d5c}.footer a:hover{color:#59b0ff}.links{display:block;font-size:1rem;margin-left:auto;margin-right:auto;margin-top:4rem;text-align:center}.links li{display:inline-block;margin-top:20px}@media screen and (max-width:480px){.container{height:auto;padding-bottom:20px;padding-top:20px}h1{font-size:30px}.link-help{white-space:nowrap}}</style><!-- Sets the page styling, IMPORTANT DO NOT REMOVE -->
</head>
<body>
@ -12,12 +12,12 @@
<div class="container-main">
<div class="alert-main">
<h1 id="headerText">Sorry, your PHP version is not supported</h1>
<p><span id="descText1">Your host needs to use PHP version {{phpversion}} or newer to run this version of Sport Stars!</span></p>
<p><span id="descText1">Your host needs to use PHP version {{phpversion}} or newer to run this version of Change Calculator!</span></p>
</div>
<div class="footer">
<ul class="links">
<li><a href="https://www.sportstars.org/">Sport Stars</a></li> -
<li><a href="https://git.vdm.dev/sportstars/">Help</a></li>
<li><a href="https://www.changecalculator.org/">Change Calculator</a></li> -
<li><a href="https://git.vdm.dev/changecalculator/">Help</a></li>
</ul>
</div>
</div>

View File

@ -1,38 +0,0 @@
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Language" content="en-GB">
<meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sport Stars: Installation Instructions</title><!-- Sets the page title, IMPORTANT DO NOT REMOVE -->
<style>html{background:#ee2a00;background:radial-gradient(ellipse at center,#f1f1f1 0,#ee2a00 100%);background-attachment:fixed;background-repeat:no-repeat}body{background-color:transparent;color:#555;font:14px/18px sans-serif}body,ol,ul{margin:0;padding:0}ol,ul{list-style:none}a{color:#0084b4;text-decoration:none}a:focus,a:hover{text-decoration:underline}p a{line-height:inherit}.container{align-items:center;display:flex;flex-direction:column;height:100vh;justify-content:center;margin:0 auto;overflow:hidden;position:relative;width:100%}.alert-main{background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:5px;box-shadow:0 0 10px rgba(0,0,0,.05);display:block;margin:0 20px;padding:20px 60px;position:relative}svg{bottom:-120px;position:absolute;right:-70px;-webkit-transform:rotate(10deg);transform:rotate(10deg);width:400px;z-index:-1}h1,p{text-rendering:optimizeLegibility;position:relative;text-align:center;z-index:10}h1{font-size:40px;font-weight:200;line-height:1;margin:18px 0 0;text-shadow:0 1px 2px rgba(0,0,0,.2)}label,p{color:#777;font-size:18px;font-weight:300;line-height:25px;margin:10px 0 20px}p a{color:#1c3d5c;font-weight:700}.link-help{background-color:#f5f5f5;border:1px solid rgba(0,0,0,.1);border-radius:.25rem;font-size:1rem;font-weight:400;padding:.4rem .85rem;text-decoration:none}.link-help:hover{background-color:#eee;text-decoration:none}.footer{font-size:11px;margin:8px 20px;text-align:left}.footer ul{margin-bottom:5px}.footer li{display:inline;line-height:20px;margin:0 5px}.footer a,.footer li{color:#1c3d5c}.footer a:hover{color:#59b0ff}.links{display:block;font-size:1rem;margin-left:auto;margin-right:auto;margin-top:4rem;text-align:center}.links li{display:inline-block;margin-top:20px}@media screen and (max-width:480px){.container{height:auto;padding-bottom:20px;padding-top:20px}h1{font-size:30px}.link-help{white-space:nowrap}}</style><!-- Sets the page styling, IMPORTANT DO NOT REMOVE -->
</head>
<body>
<div class="container">
<div class="container-main">
<div class="alert-main">
<h1 id="headerText">Installation Instructions</h1>
<p><span id="descText1">You need to manually do the following few tasks.</span></p>
<p style="text-align: left;">
1. Import the SQL tables into your database found in <u>/sql/install.sql</u>
<br />
2. Copy the <u>/config.php.example</u> file to <u>/config.php</u>
<br />
3 .Update the <u>/config.php</u> to reflect your CMS details
<br />
4. Copy the /htaccess.txt file to /.htaccess
<br />
5. <b>Remove the /installation folder</b> from you root directory
</p>
</div>
<div class="footer">
<ul class="links">
<li><a href="https://www.sportstars.org/">Sport Stars</a></li> -
<li><a href="https://git.vdm.dev/sportstars/">Help</a></li>
</ul>
</div>
</div>
</div>
<!-- source: https://github.com/joomla/joomla-cms/blob/4.1-dev/templates/system/incompatible.html -->
</body>
</html>

View File

@ -1,54 +0,0 @@
{% extends "index.twig" %}
{% block title %}Super Stars{% endblock %}
{% block content %}
<div class="uk-container uk-margin">
<h1 class="uk-article-title">Super Stars</h1>
{{ block("messages_queue", "message_queue.twig") }}
<a class="uk-button uk-button-default" href="{{ route() }}edit?task=create">Create</a>
{% if list %}
<table class="uk-table uk-table-justify uk-table-divider">
<thead>
<tr>
<th>Name</th>
<th class="uk-width-small">Age</th>
<th>Sport</th>
<th>ID</th>
<th class="uk-width-small">Action</th>
</tr>
</thead>
<tbody>
{% for item in list %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
<td>{{ item.sport }}</td>
<td>{{ item.id }}</td>
<td>
<div class="uk-button-group uk-width-1-1">
<a class="uk-button uk-button-default uk-button-small" href="{{ route() }}edit?id={{ item.id }}&task=edit">Edit</a>
<button class="uk-button uk-button-default uk-button-small" onclick="confirmDeletion('{{ item.name }}', {{ item.id }});">Delete</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a class="uk-button uk-button-default" href="{{ route() }}edit?task=create">Create</a>
{% else %}
<div class="uk-alert-primary" uk-alert>
<p>There has no athletes been added, click create to add some.</p>
</div>
{% endif %}
</div>
<script>
function confirmDeletion(name, id){
UIkit.modal.confirm('You are about to permanently delete <b>' + name + '</b>?').then(function () {
window.open("{{ route() }}edit?id=" + id + "&task=delete", "_self")
}, function () {
// we do nothing ;)
});
}
</script>
{% endblock %}

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<location path=".">
<system.webServer>
<directoryBrowse enabled="false" />
<rewrite>
<rules>
<rule name="Joomla! Rule 1" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{QUERY_STRING}" pattern="base64_encode[^(]*\([^)]*\)" ignoreCase="false" />
<add input="{QUERY_STRING}" pattern="(&gt;|%3C)([^s]*s)+cript.*(&lt;|%3E)" />
<add input="{QUERY_STRING}" pattern="GLOBALS(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />
<add input="{QUERY_STRING}" pattern="_REQUEST(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />
</conditions>
<action type="CustomResponse" url="index.php" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
</rule>
<rule name="Joomla! Rule 2">
<match url="(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{URL}" pattern="^/index.php" ignoreCase="true" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
</configuration>