From a5d7a9c7c636cfe3ec39c2e5a60e072fd836ef1f Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 29 May 2017 20:00:22 +0300 Subject: [PATCH 01/43] added slim router and composer support --- .gitignore | 4 +- .htaccess | 7 +- composer.json | 5 ++ config/config.php | 12 +++ include/dependencies.php | 5 ++ include/routes.php | 23 +++++ index.php | 182 ++------------------------------------- index_page.php | 182 +++++++++++++++++++++++++++++++++++++++ setup.php | 14 +++ 9 files changed, 255 insertions(+), 179 deletions(-) create mode 100644 composer.json create mode 100644 config/config.php create mode 100644 include/dependencies.php create mode 100644 include/routes.php create mode 100644 index_page.php create mode 100644 setup.php diff --git a/.gitignore b/.gitignore index f4107ab..5da32df 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,6 @@ Desktop.ini # MySQL Config files include/mysql_connect.php include/login/config.php -/nbproject/private/ \ No newline at end of file +/vendor +/.idea +/nbproject/private/ diff --git a/.htaccess b/.htaccess index 3c79f01..bab5b6a 100644 --- a/.htaccess +++ b/.htaccess @@ -1,4 +1,9 @@ ## Default .htaccess file ## RewriteEngine On ## RewriteCond %{HTTP_HOST} !^www\.ecdb\.net -## RewriteRule (.*) http://www.ecdb.net/$1 [R=301,L] \ No newline at end of file +## RewriteRule (.*) http://www.ecdb.net/$1 [R=301,L] + +RewriteEngine on +RewriteCond %{REQUEST_URI} !^/?index.php$ +RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png)$ +RewriteRule . index.php diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..158647e --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "slim/slim": "^3.8" + } +} diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..6d96fe0 --- /dev/null +++ b/config/config.php @@ -0,0 +1,12 @@ + 'localhost', + 'username' => 'username', + 'password' => 'password', + 'db' => 'database', +); diff --git a/include/dependencies.php b/include/dependencies.php new file mode 100644 index 0000000..7d713a0 --- /dev/null +++ b/include/dependencies.php @@ -0,0 +1,5 @@ +getContainer(); + diff --git a/include/routes.php b/include/routes.php new file mode 100644 index 0000000..c13707d --- /dev/null +++ b/include/routes.php @@ -0,0 +1,23 @@ +any('/', function ($request, $response, $args) { + require_once(__DIR__ . '/../index_page.php'); +}); +$app->any('/index.php', function ($request, $response, $args) { + require_once(__DIR__ . '/../index_page.php'); +}); + +// redirect to php file +$app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { + $filename = realpath($args['filename'] . '.php'); + if (!$filename) { + return $response->withStatus(404); + } + $base = dirname($filename); + if (dirname(__DIR__) != $base) { + return $response->withStatus(404); + } + + require_once $filename; +}); diff --git a/index.php b/index.php index 8df4ad7..0a814c0 100644 --- a/index.php +++ b/index.php @@ -1,182 +1,10 @@ - - - - - - - - - - Home - ecDB - - - -
- - - - - - - -
- +$app = new \Slim\App(new \Slim\Container); - - - - - - - - - - - - - - - - - - Index(); - ?> - -
- - Name - - Category - - Package - - Pins - - Image - - Datasheet - - SMD - - Price - - Quantity - - Comment -
-
- - - - -
- - +$app->run(); diff --git a/index_page.php b/index_page.php new file mode 100644 index 0000000..f8af78f --- /dev/null +++ b/index_page.php @@ -0,0 +1,182 @@ + + + + + + + + + + + Home - ecDB + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + Index(); + ?> + +
+ + Name + + Category + + Package + + Pins + + Image + + Datasheet + + SMD + + Price + + Quantity + + Comment +
+
+ + + + +
+ + diff --git a/setup.php b/setup.php new file mode 100644 index 0000000..4cab385 --- /dev/null +++ b/setup.php @@ -0,0 +1,14 @@ + Date: Mon, 29 May 2017 20:03:52 +0300 Subject: [PATCH 02/43] added smarty support --- composer.json | 3 ++- include/dependencies.php | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 158647e..3499318 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "require": { - "slim/slim": "^3.8" + "slim/slim": "^3.8", + "smarty/smarty": "^3.1" } } diff --git a/include/dependencies.php b/include/dependencies.php index 7d713a0..9fe49b5 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -3,3 +3,11 @@ $container = $app->getContainer(); +$container['view'] = function ($container) use ($ECDB_VERSION) { + $smarty = new Smarty(); + $smarty->setTemplateDir(__DIR__ . '/../views'); + $smarty->assign('ECDB_VERSION', $ECDB_VERSION); + $smarty->error_reporting = E_ALL & ~E_NOTICE; + + return $smarty; +}; From 0851c9635dd6518420cdb7a5523933e0d69f99fa Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 29 May 2017 20:04:59 +0300 Subject: [PATCH 03/43] added doctrine/dbal support --- composer.json | 1 + include/dependencies.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/composer.json b/composer.json index 3499318..724ebc7 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "require": { + "doctrine/dbal": "*", "slim/slim": "^3.8", "smarty/smarty": "^3.1" } diff --git a/include/dependencies.php b/include/dependencies.php index 9fe49b5..3ba3ba6 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -11,3 +11,17 @@ return $smarty; }; + +$container['db'] = function ($container) use ($config) { + $c = new \Doctrine\DBAL\Configuration(); + + $connectionParams = array( + 'dbname' => $config['db']['db'], + 'user' => $config['db']['username'], + 'password' => $config['db']['password'], + 'host' => $config['db']['host'], + 'driver' => 'pdo_mysql', + ); + + return \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $c); +}; From 94732129a3276e2462920505de89a77aa3c4e5d3 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 29 May 2017 20:06:20 +0300 Subject: [PATCH 04/43] autoload controllers with composer --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index 724ebc7..b20f952 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,9 @@ { + "autoload": { + "psr-4": { + "Ecdb\\Controllers\\": "controllers/" + } + }, "require": { "doctrine/dbal": "*", "slim/slim": "^3.8", From 6c8072ba7c6df1e39d44f73d2307bc24e1b2ce83 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 29 May 2017 20:09:06 +0300 Subject: [PATCH 05/43] added first LoginController and refactored all authentication related pages --- controllers/BaseController.php | 39 +++++++++++ controllers/LoginController.php | 79 +++++++++++++++++++++ include/dependencies.php | 18 +++++ include/header.php | 2 +- include/login/auth.php | 2 +- include/routes.php | 5 ++ login-exec.php | 83 ---------------------- login-failed.php | 72 -------------------- login.php | 117 -------------------------------- logout.php | 90 ------------------------ register-success.php | 2 +- views/layout.tpl | 115 +++++++++++++++++++++++++++++++ views/login.tpl | 48 +++++++++++++ 13 files changed, 307 insertions(+), 365 deletions(-) create mode 100644 controllers/BaseController.php create mode 100644 controllers/LoginController.php delete mode 100644 login-exec.php delete mode 100644 login-failed.php delete mode 100644 login.php delete mode 100644 logout.php create mode 100644 views/layout.tpl create mode 100644 views/login.tpl diff --git a/controllers/BaseController.php b/controllers/BaseController.php new file mode 100644 index 0000000..9f9098d --- /dev/null +++ b/controllers/BaseController.php @@ -0,0 +1,39 @@ +app = $app; + $this->view = $app->getContainer()->get('view'); + $this->db = $app->getContainer()->get('db'); + + if (!empty($_SESSION['ERRMSG_ARR'])) { + $this->view->assign('errors', $_SESSION['ERRMSG_ARR']); + unset($_SESSION['ERRMSG_ARR']); + } + if (!empty($_SESSION['messages'])) { + $this->view->assign('messages', $_SESSION['messages']); + unset($_SESSION['messages']); + } + } + +} \ No newline at end of file diff --git a/controllers/LoginController.php b/controllers/LoginController.php new file mode 100644 index 0000000..84f9356 --- /dev/null +++ b/controllers/LoginController.php @@ -0,0 +1,79 @@ +withRedirect('login'); + } + + public function auth(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + //Array to store validation errors + $errmsg_arr = array(); + + //Sanitize the POST values + $login = $req->getParam('login'); + $password = $req->getParam('password'); + + //Input Validations + if (!$login) { + $errmsg_arr[] = 'Login ID missing'; + } + if (!$password) { + $errmsg_arr[] = 'Password missing'; + } + + //If there are input validations, redirect back to the login form + if ($errmsg_arr) { + $_SESSION['ERRMSG_ARR'] = $errmsg_arr; + + return $response->withRedirect('login'); + } + + $data = $this->db->fetchAssoc('SELECT * FROM members WHERE login=? AND passwd=?', array( + $login, + md5($_POST['password']), + )); + + if (!$data) { + $_SESSION['ERRMSG_ARR'] = 'Invalid username/password'; + + return $response->withRedirect('login'); + } + + //Login Successful + session_regenerate_id(true); + $_SESSION['SESS_MEMBER_ID'] = $data['member_id']; + $_SESSION['SESS_FIRST_NAME'] = $data['firstname']; + $_SESSION['SESS_LAST_NAME'] = $data['lastname']; + $_SESSION['SESS_IS_ADMIN'] = intval($data['admin']); + session_write_close(); + + $member_id = $_SESSION['SESS_MEMBER_ID']; + $this->db->insert('members_stats', array('members_stats_member' => $member_id)); + + return $response->withRedirect('index.php'); + } + + public function index(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + //Unset the variables stored in session + unset($_SESSION['SESS_MEMBER_ID']); + unset($_SESSION['SESS_FIRST_NAME']); + unset($_SESSION['SESS_LAST_NAME']); + unset($_SESSION['SESS_IS_ADMIN']); + + $this->view->assign('selected_menu', 'Login'); + + return $this->view->display('login.tpl'); + } + +} + diff --git a/include/dependencies.php b/include/dependencies.php index 3ba3ba6..2e5800e 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -3,12 +3,30 @@ $container = $app->getContainer(); +$container['LoginController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\LoginController($app); +}; $container['view'] = function ($container) use ($ECDB_VERSION) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); $smarty->assign('ECDB_VERSION', $ECDB_VERSION); $smarty->error_reporting = E_ALL & ~E_NOTICE; + /** @var \Doctrine\DBAL\Connection $db */ + $db = $container['db']; + if (isset($_SESSION['SESS_IS_ADMIN']) && $_SESSION['SESS_IS_ADMIN'] == 1) { + $data1 = $db->fetchAssoc('SELECT COUNT(member_id) AS count FROM members'); + $data2 = $db->fetchAssoc('SELECT COUNT(id) AS count FROM data'); + $data3 = $db->fetchAssoc('SELECT COUNT(project_id) AS count FROM projects'); + + $ADMIN_STATS = array( + 'members' => $data1['count'], + 'components' => $data2['count'], + 'projects' => $data3['count'], + ); + $smarty->assign('ADMIN_STATS', $ADMIN_STATS); + } + return $smarty; }; diff --git a/include/header.php b/include/header.php index 70d5726..376173a 100644 --- a/include/header.php +++ b/include/header.php @@ -18,7 +18,7 @@ echo ' '; if(isset($_POST['submit']) && $_SERVER["REQUEST_URI"] == '/ecdb/my.php') { echo $_POST['lastname']; } else { echo $headername['lastname']; } ?> - - Sign out + - Sign out
diff --git a/include/login/auth.php b/include/login/auth.php index ed3fcbd..69461d1 100644 --- a/include/login/auth.php +++ b/include/login/auth.php @@ -8,7 +8,7 @@ } else { - header("location: login.php"); + header("location: login"); exit(); } } diff --git a/include/routes.php b/include/routes.php index c13707d..b153831 100644 --- a/include/routes.php +++ b/include/routes.php @@ -8,6 +8,11 @@ require_once(__DIR__ . '/../index_page.php'); }); +// login/logout +$app->get('/login', 'LoginController:index'); +$app->post('/auth', 'LoginController:auth'); +$app->get('/logout', 'LoginController:logout'); + // redirect to php file $app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { $filename = realpath($args['filename'] . '.php'); diff --git a/login-exec.php b/login-exec.php deleted file mode 100644 index f166b7d..0000000 --- a/login-exec.php +++ /dev/null @@ -1,83 +0,0 @@ - \ No newline at end of file diff --git a/login-failed.php b/login-failed.php deleted file mode 100644 index a1ce423..0000000 --- a/login-failed.php +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - Login - ecDB - - - - -
- - - - - - - - - - -
- -
- Login failed, please try again. -
- -
-
-
- -
-
- -
-
-
- -
-
-
-
- -
-
-
-
-
-
-
- - - - - - -
- - diff --git a/login.php b/login.php deleted file mode 100644 index f1eeefb..0000000 --- a/login.php +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - ecDB - electronics component DataBase - - - - - - - - -
- - - - - - - - - - -
-
- 0 ) { - echo '
'; - echo '
    '; - foreach($_SESSION['ERRMSG_ARR'] as $msg) { - echo '
  • ',$msg,'
  • '; - } - echo '
'; - echo '
'; - unset($_SESSION['ERRMSG_ARR']); - } - ?> -
- -
-
-
- -
-
-
- You want to build something and need some components for your project. - You don't know if you have those components, or where they are. - This is a problem many of us recognise. - We want to change that for you by making a online inventory system for your electronic components that is easy to use. - Add your components. Search to find it, and then use it! -
- -
-
- -
To try ecDB, login with demo:demo
-
-
- -
-
-
-
- -
-
-
-
-
-
-
- - - - - - -
- - diff --git a/logout.php b/logout.php deleted file mode 100644 index 9cdec8d..0000000 --- a/logout.php +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - Login - ecDB - - - - - -
- - - - - - - - - - -
-
- You have successfully signed out of your account. -
- -
-
-
- You want to build something and need some components for your project. - You don't know if you have those components, or where they are. - This is a problem many of us recognise. - We want to change that for you by making a online inventory system for your electronic components that is easy to use. - Add your components. Search to find it, and then use it! -
-
-
- -
-
-
- -
-
-
-
- -
-
-
-
-
-
- - -
- - - - - - -
- - - diff --git a/register-success.php b/register-success.php index a1a7966..dfac04e 100644 --- a/register-success.php +++ b/register-success.php @@ -44,7 +44,7 @@ Please login

-
+ diff --git a/views/layout.tpl b/views/layout.tpl new file mode 100644 index 0000000..b57def9 --- /dev/null +++ b/views/layout.tpl @@ -0,0 +1,115 @@ + + + + + + + + + + {block name=title}Home - ecDB{/block} + {block name=head}{/block} + + +
+ + + + + + +
+
+ {if !empty($errors)} + {foreach from=$errors item=$msg} +
+
  • {$msg}
+
+ {/foreach} + {/if} + {if !empty($messages)} + {foreach from=$messages item=$msg} +
+ {$msg} +
+ {/foreach} + {/if} + {if !empty($info)} + {foreach from=$info item=$msg} +
+ {$msg} +
+ {/foreach} + {/if} +
+ {block name=body}{/block} +
+ +
+
+
+ © 2010 - {'Y'|@date} ecDB - Created by Nils Fredriksson + - Contact us + - Terms & Privacy + - About +
+ {if $smarty.session.SESS_IS_ADMIN} +
+ + {$ADMIN_STATS.members} + members, + + {$ADMIN_STATS.components} + components and + + {$ADMIN_STATS.projects} + projects. +
+ {/if} +
+
+ Design by +
+
+ +
+ + diff --git a/views/login.tpl b/views/login.tpl new file mode 100644 index 0000000..502c17b --- /dev/null +++ b/views/login.tpl @@ -0,0 +1,48 @@ +{extends file='layout.tpl'} + +{block name=title}ecDB - electronics component DataBase{/block} + +{block name=head}{/block} + +{block name=body} + + +
+
+
+
+ +
+ You want to build something and need some components for your project. + You don't know if you have those components, or where they are. + This is a problem many of us recognise. + We want to change that for you by making a online inventory system for your electronic components + that is easy to use. + Add your components. Search to find it, and then use it! +
+ +
+
+ +
+ To try ecDB, login with demo:demo
+ +
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +{/block} \ No newline at end of file From 5078812bdcc3275e2f1ccdbbf8f91992bb3fd49b Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 29 May 2017 21:02:50 +0300 Subject: [PATCH 06/43] added registration controller and refactored registration pages --- controllers/RegisterController.php | 99 ++++++++++++++++++++++ donate.php | 2 +- include/dependencies.php | 3 + include/routes.php | 2 + register-exec.php | 130 ----------------------------- register-success.php | 72 ---------------- register.php | 107 ------------------------ views/layout.tpl | 2 +- views/registration.tpl | 55 ++++++++++++ 9 files changed, 161 insertions(+), 311 deletions(-) create mode 100644 controllers/RegisterController.php delete mode 100644 register-exec.php delete mode 100644 register-success.php delete mode 100644 register.php create mode 100644 views/registration.tpl diff --git a/controllers/RegisterController.php b/controllers/RegisterController.php new file mode 100644 index 0000000..1e36903 --- /dev/null +++ b/controllers/RegisterController.php @@ -0,0 +1,99 @@ +view->assign('selected_menu', 'Register'); + } + + public function index(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + return $this->view->display('registration.tpl'); + } + + public function register(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + //Array to store validation errors + $errors = array(); + + //Sanitize the POST values + $fname = $req->getParam('fname'); + $lname = $req->getParam('lname'); + $login = $req->getParam('login'); + $mail = $req->getParam('mail'); + $password = $req->getParam('password'); + $cpassword = $req->getParam('cpassword'); + + //Input Validations + if (!$fname) { + $errors[] = 'First name missing'; + } else if (strlen($fname) < 2) { + $errors[] = 'Minimum of 2 chars in first name.'; + } + if (!$lname) { + $errors[] = 'Last name missing'; + } else if (strlen($lname) < 2) { + $errors[] = 'Minimum of 2 chars in last name.'; + } + if (!$login) { + $errors[] = 'Username missing'; + } else if (strlen($login) < 2) { + $errors[] = 'Minimum of 2 chars in username.'; + } + if (!$mail) { + $errors[] = 'Mail missing'; + } else if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) { + $errors[] = 'Invalid e-mail address'; + } + if (!$password) { + $errors[] = 'Password missing'; + } else if (strlen($password) < 5) { + $errors[] = 'Minimum of 5 chars in password.'; + } + if (!$cpassword) { + $errors[] = 'Confirm password missing'; + } else if (strcmp($password, $cpassword) != 0) { + $errors[] = 'Passwords do not match'; + } + + //Check for duplicate login ID + if ($login) { + $data = $this->db->fetchAssoc('SELECT COUNT(*) as count FROM members WHERE login=?', array( + $login, + )); + if ($data['count']) { + $errors[] = 'Username already in use'; + } + } + + //If there are input validations, redirect back to the registration form + if ($errors) { + $_SESSION['ERRMSG_ARR'] = $errors; + + $this->view->assign('fname', $fname); + $this->view->assign('lname', $lname); + $this->view->assign('login', $login); + $this->view->assign('mail', $mail); + return $this->view->display('registration.tpl'); + } + + //Create INSERT query + $added = $this->db->insert('members', array( + 'firstname' => $fname, + 'lastname' => $lname, + 'login' => $login, + 'mail' => $mail, + 'passwd' => md5($_POST['password']), + )); + + $_SESSION['messages'][] = 'User created'; + + // TODO: just do auto-login, why user has to login + return $response->withRedirect('login'); + } + +} + diff --git a/donate.php b/donate.php index c81149a..9687d58 100644 --- a/donate.php +++ b/donate.php @@ -38,7 +38,7 @@ echo '
Login
- - - - - - - - - - - - -
Login
Password
 
- -
- - - - - - - - - diff --git a/register.php b/register.php deleted file mode 100644 index 8728858..0000000 --- a/register.php +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - Register - ecDB - - - - - -
- - - - - - - - - - -
- - 0 ) { - echo '
'; - echo '
    '; - foreach($_SESSION['ERRMSG_ARR'] as $msg) { - echo '
  • ',$msg,'
  • '; - } - echo '
'; - echo '
'; - unset($_SESSION['ERRMSG_ARR']); - } - ?> -
-
-
- You want to build something and need some components for your project. - You don't know if you have those components, or where they are. - This is a problem many of us recognise. - We want to change that for you by making a online inventory system for your electronic components that is easy to use. - Add your components. Search to find it, and then use it! -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- By registering you accept the Terms and Contidions.

-
- -
-
-
-
-
-
-
- - - - - - -
- - diff --git a/views/layout.tpl b/views/layout.tpl index b57def9..e33e2d7 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -48,7 +48,7 @@ {/if} {if !$smarty.session.SESS_MEMBER_ID}
  • Login
  • -
  • Register
  • +
  • Register
  • About
  • Blog
  • {/if} diff --git a/views/registration.tpl b/views/registration.tpl new file mode 100644 index 0000000..b1caa7d --- /dev/null +++ b/views/registration.tpl @@ -0,0 +1,55 @@ +{extends file='layout.tpl'} + +{block name=title}Register - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + + +
    +
    +
    + You want to build something and need some components for your project. + You don't know if you have those components, or where they are. + This is a problem many of us recognise. + We want to change that for you by making a online inventory system for your electronic components that is easy to use. + Add your components. Search to find it, and then use it! +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + By registering you accept the Terms and Contidions.

    +
    + +
    +
    +
    +
    +
    +
    + +{/block} \ No newline at end of file From 7e43987f9f0172c130a4d07d17f18d4b6c211309 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 29 May 2017 21:42:19 +0300 Subject: [PATCH 07/43] added about controller and refactored about page --- about.php | 94 --------------------------------- controllers/AboutController.php | 13 +++++ donate.php | 2 +- include/dependencies.php | 3 ++ include/routes.php | 1 + views/about.tpl | 56 ++++++++++++++++++++ views/layout.tpl | 4 +- 7 files changed, 76 insertions(+), 97 deletions(-) delete mode 100644 about.php create mode 100644 controllers/AboutController.php create mode 100644 views/about.tpl diff --git a/about.php b/about.php deleted file mode 100644 index 325cc5a..0000000 --- a/about.php +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - About - ecDB - - - - -
    - - - - - - - - - - -
    -
    -
    -
    - Check out the new ecDB blog. Or follow @ecDBnet at Twitter to get the latest updates! -
    -

    What is ecDB?

    - - ecDB is basically a place where you, as an electronics hobbyist (or professional) can add your own components to your personal database to keep track of what components you own, where they are, how many you own and so on. - -

    - -

    -

    Who & Why?

    - - ecDB is created by Nils Fredriksson and designed by Buildlog.

    - - Me, Nils, have always wanted to have a system like this to keep track of what component I own. Before I created this system I (I guess you too...) had to dig through boxes filled with components to maybe find that component I needed. This is an unnecessary task to do, it not only takes time, and it also can be really frustrating not to find that component you are looking for. So I ended up creating this website where I easily can keep track of my components! - -

    -

    What does it cost?

    - - ecDB is completely free!
    - But if you like ecDB you can use this button to donate us some money. -
    - - - -
    - -
    -

    Is ecDB really done?

    - No! ecDB is still under development. Here are some of the upcoming features:

    - - - Public components - a place where you easily can trade components.
    - - View to physically print the personal database. Old-school typewritten text and nice colums!
    - - Datasheet and picture uploading.
    - - Advanced component search with parameters.
    - - Log for each component. See when the component last was used/edited/bought etc.
    - - Barcode implementation for easy storage management.
    - - Import and export of personal database to text/spreadsheet.
    - - Quick edit function of component data directly from the database view.
    - - Add personal categories and fields.
    - - Borrow component data from other components in the database to easily add components. -
    -
    -
    -
    - - - - - - -
    - - \ No newline at end of file diff --git a/controllers/AboutController.php b/controllers/AboutController.php new file mode 100644 index 0000000..a5c70d1 --- /dev/null +++ b/controllers/AboutController.php @@ -0,0 +1,13 @@ +view->assign('selected_menu', 'About'); + return $this->view->display('about.tpl'); + } + +} + diff --git a/donate.php b/donate.php index 9687d58..6f61235 100644 --- a/donate.php +++ b/donate.php @@ -39,7 +39,7 @@ echo ''; echo ''; diff --git a/include/dependencies.php b/include/dependencies.php index 0836415..3bdb83a 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -9,6 +9,9 @@ $container['RegisterController'] = function ($container) use ($app) { return new \Ecdb\Controllers\RegisterController($app); }; +$container['AboutController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\AboutController($app); +}; $container['view'] = function ($container) use ($ECDB_VERSION) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); diff --git a/include/routes.php b/include/routes.php index 97fcd60..686348e 100644 --- a/include/routes.php +++ b/include/routes.php @@ -14,6 +14,7 @@ $app->get('/logout', 'LoginController:logout'); $app->get('/register', 'RegisterController:index'); $app->post('/register', 'RegisterController:register'); +$app->get('/about', 'AboutController:index'); // redirect to php file $app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { diff --git a/views/about.tpl b/views/about.tpl new file mode 100644 index 0000000..b5c9a35 --- /dev/null +++ b/views/about.tpl @@ -0,0 +1,56 @@ +{extends file='layout.tpl'} + +{block name=title}About - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + +
    +
    +
    + Check out the new ecDB blog. Or follow @ecDBnet at Twitter to get the latest updates! +
    +

    What is ecDB?

    + + ecDB is basically a place where you, as an electronics hobbyist (or professional) can add your own components to your personal database to keep track of what components you own, where they are, how many you own and so on. + +

    + +

    +

    Who & Why?

    + + ecDB is created by Nils Fredriksson and designed by Buildlog.

    + + Me, Nils, have always wanted to have a system like this to keep track of what component I own. Before I created this system I (I guess you too...) had to dig through boxes filled with components to maybe find that component I needed. This is an unnecessary task to do, it not only takes time, and it also can be really frustrating not to find that component you are looking for. So I ended up creating this website where I easily can keep track of my components! + +

    +

    What does it cost?

    + + ecDB is completely free!
    + But if you like ecDB you can use this button to donate us some money. +
    + + + +
    + +
    +

    Is ecDB really done?

    + No! ecDB is still under development. Here are some of the upcoming features:

    + + - Public components - a place where you easily can trade components.
    + - View to physically print the personal database. Old-school typewritten text and nice colums!
    + - Datasheet and picture uploading.
    + - Advanced component search with parameters.
    + - Log for each component. See when the component last was used/edited/bought etc.
    + - Barcode implementation for easy storage management.
    + - Import and export of personal database to text/spreadsheet.
    + - Quick edit function of component data directly from the database view.
    + - Add personal categories and fields.
    + - Borrow component data from other components in the database to easily add components. +
    +
    +
    + +{/block} \ No newline at end of file diff --git a/views/layout.tpl b/views/layout.tpl index e33e2d7..2a16741 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -49,7 +49,7 @@ {if !$smarty.session.SESS_MEMBER_ID}
  • Login
  • Register
  • -
  • About
  • +
  • About
  • Blog
  • {/if} @@ -89,7 +89,7 @@ © 2010 - {'Y'|@date} ecDB - Created by Nils Fredriksson - Contact us - Terms & Privacy - - About + - About {if $smarty.session.SESS_IS_ADMIN}
    From e30cd455debd3f72b85b661b3beb293cf71acab5 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 29 May 2017 23:20:31 +0300 Subject: [PATCH 08/43] added project controller and refactored projects list page --- controllers/BaseController.php | 4 ++ controllers/ProjectController.php | 70 +++++++++++++++++++++++ include/dependencies.php | 3 + include/include_proj_add.php | 30 ---------- include/routes.php | 2 + proj_list.php | 94 ------------------------------- views/projects-list.tpl | 58 +++++++++++++++++++ 7 files changed, 137 insertions(+), 124 deletions(-) create mode 100644 controllers/ProjectController.php delete mode 100644 include/include_proj_add.php delete mode 100644 proj_list.php create mode 100644 views/projects-list.tpl diff --git a/controllers/BaseController.php b/controllers/BaseController.php index 9f9098d..514d6fe 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -34,6 +34,10 @@ public function __construct($app) { $this->view->assign('messages', $_SESSION['messages']); unset($_SESSION['messages']); } + if (!empty($_SESSION['info'])) { + $this->view->assign('info', $_SESSION['info']); + unset($_SESSION['info']); + } } } \ No newline at end of file diff --git a/controllers/ProjectController.php b/controllers/ProjectController.php new file mode 100644 index 0000000..23fe3f7 --- /dev/null +++ b/controllers/ProjectController.php @@ -0,0 +1,70 @@ +getParam('name'); + + if (!$name) { + $_SESSION['ERRMSG_ARR'] = array( + 'You have to specify a name!', + ); + + return $response->withRedirect('proj_list'); + } + + $added = $this->db->insert('projects', array( + 'project_owner' => $owner, + 'project_name' => $name, + )); + + $_SESSION['messages'] = array( + 'Project added!', + ); + return $response->withRedirect('proj_list'); + } + + public function projects(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + + $owner = $_SESSION['SESS_MEMBER_ID']; + + $order = strtolower($req->getParam('order', 'asc')) == 'asc' ? 'asc' : 'desc'; + $sql = "SELECT projects.* + , m.currency currency + , SUM(pd1.projects_data_id) AS qty + , CAST(data.price as decimal(14, 2)) * pd1.projects_data_quantity AS total_price + FROM projects + LEFT JOIN projects_data AS pd1 ON pd1.projects_data_project_id = projects.project_id + LEFT JOIN data ON data.id = pd1.projects_data_component_id + JOIN members m ON project_owner = m.member_id + WHERE project_owner = ? + group by projects.project_id + ORDER BY project_name ".$order; + $data = $this->db->fetchAll($sql, array($owner)); + + $this->view->assign('projects', $data); + + if ($owner) { + $data = $this->db->fetchAssoc('SELECT COUNT(*) c FROM projects WHERE project_owner = ?', array( + $owner, + )); + if (empty($data['c'])) { + $_SESSION['info'] = array( + 'To create a BOM-list (Bill Of Material) you have to first create a project. You will then be able to add your components to your project and automaticly create a BOM-list.', + ); + } + } + + $this->view->assign('selected_menu', 'projects'); + $this->view->assign('order', $order); + + return $this->view->display('projects-list.tpl'); + } + +} + diff --git a/include/dependencies.php b/include/dependencies.php index 3bdb83a..d4ccc0c 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -12,6 +12,9 @@ $container['AboutController'] = function ($container) use ($app) { return new \Ecdb\Controllers\AboutController($app); }; +$container['ProjectController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\ProjectController($app); +}; $container['view'] = function ($container) use ($ECDB_VERSION) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); diff --git a/include/include_proj_add.php b/include/include_proj_add.php deleted file mode 100644 index f85bfd3..0000000 --- a/include/include_proj_add.php +++ /dev/null @@ -1,30 +0,0 @@ -'; - echo 'You have to specify a name!'; - echo '
    '; - } - else { - $sql="INSERT into projects (project_owner, project_name) VALUES ('$owner', '$name')"; - $sql_exec = mysql_query($sql); - - $proj_id = mysql_insert_id(); - - echo '
    '; - echo 'Project added!'; - echo '
    '; - } - } - } -} -?> \ No newline at end of file diff --git a/include/routes.php b/include/routes.php index 686348e..4e0aace 100644 --- a/include/routes.php +++ b/include/routes.php @@ -15,6 +15,8 @@ $app->get('/register', 'RegisterController:index'); $app->post('/register', 'RegisterController:register'); $app->get('/about', 'AboutController:index'); +$app->get('/proj_list', 'ProjectController:projects'); +$app->post('/project_add', 'ProjectController:add'); // redirect to php file $app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { diff --git a/proj_list.php b/proj_list.php deleted file mode 100644 index 65fd044..0000000 --- a/proj_list.php +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - Your Projects - ecDB - - - - - -
    - - - - - - - - - - -
    - AddProj(); - - $proj_query = mysql_query("SELECT * FROM projects WHERE project_owner= $owner"); - if(mysql_num_rows($proj_query) == 0){ - echo '
    To create a BOM-list (Bill Of Material) you have to first create a project. You will then be able to add your components to your project and automaticly create a BOM-list.
    '; - } - ?> -
    -
    - -
    -
    -
    -
    - -
    -
    -
    - -
    - - - - - - - - - - - - ProjList(); - ?> - -
    Name - Number of componentsTotal cost
    -
    - - - - -
    - - diff --git a/views/projects-list.tpl b/views/projects-list.tpl new file mode 100644 index 0000000..ca7f8d3 --- /dev/null +++ b/views/projects-list.tpl @@ -0,0 +1,58 @@ +{extends file='layout.tpl'} + +{block name=title}Your Projects - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + + + {if $smarty.session.SESS_MEMBER_ID} + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + {/if} + + + + + + + + + + + + {foreach from=$projects item=project} + + {if $smarty.session.SESS_MEMBER_ID} + + {else} + + {/if} + + + + + {/foreach} + +
    Name + Number of ComponentsTotal cost
    {$project.project_name}{$project.qty|default:'-'} + {if $project.total_price} + {$project.total_price} {$project.currency|default:'-'} + {else} + - + {/if} +
    + +{/block} \ No newline at end of file From 482dfdff5c51a1d23a56c111d30aa62df049438e Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Tue, 30 May 2017 10:38:46 +0300 Subject: [PATCH 09/43] added middleware that handles all flash messages and use absolute urls --- controllers/BaseController.php | 13 ------------- include/middlewares.php | 22 ++++++++++++++++++++++ index.php | 21 +++++++++++---------- views/login.tpl | 2 +- views/registration.tpl | 4 ++-- 5 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 include/middlewares.php diff --git a/controllers/BaseController.php b/controllers/BaseController.php index 514d6fe..686d344 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -25,19 +25,6 @@ public function __construct($app) { $this->app = $app; $this->view = $app->getContainer()->get('view'); $this->db = $app->getContainer()->get('db'); - - if (!empty($_SESSION['ERRMSG_ARR'])) { - $this->view->assign('errors', $_SESSION['ERRMSG_ARR']); - unset($_SESSION['ERRMSG_ARR']); - } - if (!empty($_SESSION['messages'])) { - $this->view->assign('messages', $_SESSION['messages']); - unset($_SESSION['messages']); - } - if (!empty($_SESSION['info'])) { - $this->view->assign('info', $_SESSION['info']); - unset($_SESSION['info']); - } } } \ No newline at end of file diff --git a/include/middlewares.php b/include/middlewares.php new file mode 100644 index 0000000..f15ee02 --- /dev/null +++ b/include/middlewares.php @@ -0,0 +1,22 @@ +add(function ($request, $response, $next) { + // set base url variable in view + $base_url = $request->getUri()->getBaseUrl(); + $this->view->assign('base_url', $base_url); + + if (!empty($_SESSION['ERRMSG_ARR'])) { + $this->view->assign('errors', $_SESSION['ERRMSG_ARR']); + unset($_SESSION['ERRMSG_ARR']); + } + if (!empty($_SESSION['messages'])) { + $this->view->assign('messages', $_SESSION['messages']); + unset($_SESSION['messages']); + } + if (!empty($_SESSION['info'])) { + $this->view->assign('info', $_SESSION['info']); + unset($_SESSION['info']); + } + + return $next($request, $response); +}); diff --git a/index.php b/index.php index 0a814c0..4738bed 100644 --- a/index.php +++ b/index.php @@ -1,10 +1,11 @@ -run(); +run(); diff --git a/views/login.tpl b/views/login.tpl index 502c17b..ec620c8 100644 --- a/views/login.tpl +++ b/views/login.tpl @@ -21,7 +21,7 @@ Add your components. Search to find it, and then use it! -
    +
    diff --git a/views/registration.tpl b/views/registration.tpl index b1caa7d..7709210 100644 --- a/views/registration.tpl +++ b/views/registration.tpl @@ -16,7 +16,7 @@ We want to change that for you by making a online inventory system for your electronic components that is easy to use. Add your components. Search to find it, and then use it!
    - +
    @@ -42,7 +42,7 @@
    - By registering you accept the Terms and Contidions.

    + By registering you accept the Terms and Contidions.

    From 38fb7ca143f2fdf7724b72f4107058e3f8308544 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Wed, 31 May 2017 22:45:22 +0300 Subject: [PATCH 10/43] added names to routes so redirect can be done by route name --- controllers/BaseController.php | 10 ++++++++++ controllers/ProjectController.php | 2 +- include/routes.php | 14 +++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/controllers/BaseController.php b/controllers/BaseController.php index 686d344..9649671 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -27,4 +27,14 @@ public function __construct($app) { $this->db = $app->getContainer()->get('db'); } + protected function redirect($response, $path_or_name, $args=array()) { + try { + $path = $this->app->getContainer()->get('router')->pathFor($path_or_name, $args); + } catch (\Exception $e) { + $path = $path_or_name; + } + + return $response->withRedirect($path); + } + } \ No newline at end of file diff --git a/controllers/ProjectController.php b/controllers/ProjectController.php index 23fe3f7..473fca8 100644 --- a/controllers/ProjectController.php +++ b/controllers/ProjectController.php @@ -25,7 +25,7 @@ public function add(\Slim\Http\Request $req, \Slim\Http\Response $response, $arg $_SESSION['messages'] = array( 'Project added!', ); - return $response->withRedirect('proj_list'); + return $this->redirect($response, 'projects'); } public function projects(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { diff --git a/include/routes.php b/include/routes.php index 4e0aace..b18e4b4 100644 --- a/include/routes.php +++ b/include/routes.php @@ -9,14 +9,14 @@ }); // login/logout -$app->get('/login', 'LoginController:index'); -$app->post('/auth', 'LoginController:auth'); -$app->get('/logout', 'LoginController:logout'); -$app->get('/register', 'RegisterController:index'); +$app->get('/login', 'LoginController:index')->setName('index'); +$app->post('/auth', 'LoginController:auth')->setName('auth'); +$app->get('/logout', 'LoginController:logout')->setName('logout'); +$app->get('/register', 'RegisterController:index')->setName('register'); $app->post('/register', 'RegisterController:register'); -$app->get('/about', 'AboutController:index'); -$app->get('/proj_list', 'ProjectController:projects'); -$app->post('/project_add', 'ProjectController:add'); +$app->get('/about', 'AboutController:index')->setName('about'); +$app->get('/proj_list', 'ProjectController:projects')->setName('projects'); +$app->post('/project_add', 'ProjectController:add')->setName('project_add'); // redirect to php file $app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { From 243de1725a218b93d6039797fe76d7c5da1adf20 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Wed, 31 May 2017 22:48:13 +0300 Subject: [PATCH 11/43] improve keeping session messages on unexpected errors and redirects --- controllers/BaseController.php | 18 +++++++++++++++ controllers/LoginController.php | 2 +- controllers/RegisterController.php | 2 +- include/middlewares.php | 37 +++++++++++++++++++++--------- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/controllers/BaseController.php b/controllers/BaseController.php index 9649671..b3fdbad 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -27,6 +27,24 @@ public function __construct($app) { $this->db = $app->getContainer()->get('db'); } + protected function render($template_filename) { + + $message_types = array( + 'ERRMSG_ARR' => 'errors', + 'messages' => 'messages', + 'info' => 'info', + ); + foreach ($message_types as $var_session=>$var_tpl) { + if (!empty($_SESSION[$var_session])) { + $existing_messages = empty($this->view->tpl_vars[$var_tpl]->value) ? array() : $this->view->tpl_vars[$var_tpl]->value; + $this->view->assign($var_tpl, array_merge($existing_messages, $_SESSION[$var_session])); + unset($_SESSION[$var_session]); + } + } + + return $this->view->display($template_filename); + } + protected function redirect($response, $path_or_name, $args=array()) { try { $path = $this->app->getContainer()->get('router')->pathFor($path_or_name, $args); diff --git a/controllers/LoginController.php b/controllers/LoginController.php index 84f9356..3592b1f 100644 --- a/controllers/LoginController.php +++ b/controllers/LoginController.php @@ -60,7 +60,7 @@ public function auth(\Slim\Http\Request $req, \Slim\Http\Response $response, $ar $member_id = $_SESSION['SESS_MEMBER_ID']; $this->db->insert('members_stats', array('members_stats_member' => $member_id)); - return $response->withRedirect('index.php'); + return $this->redirect($response, 'index'); } public function index(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { diff --git a/controllers/RegisterController.php b/controllers/RegisterController.php index 1e36903..50835e9 100644 --- a/controllers/RegisterController.php +++ b/controllers/RegisterController.php @@ -77,7 +77,7 @@ public function register(\Slim\Http\Request $req, \Slim\Http\Response $response, $this->view->assign('lname', $lname); $this->view->assign('login', $login); $this->view->assign('mail', $mail); - return $this->view->display('registration.tpl'); + return $this->render('registration.tpl'); } //Create INSERT query diff --git a/include/middlewares.php b/include/middlewares.php index f15ee02..89611a5 100644 --- a/include/middlewares.php +++ b/include/middlewares.php @@ -5,18 +5,33 @@ $base_url = $request->getUri()->getBaseUrl(); $this->view->assign('base_url', $base_url); - if (!empty($_SESSION['ERRMSG_ARR'])) { - $this->view->assign('errors', $_SESSION['ERRMSG_ARR']); - unset($_SESSION['ERRMSG_ARR']); - } - if (!empty($_SESSION['messages'])) { - $this->view->assign('messages', $_SESSION['messages']); - unset($_SESSION['messages']); + $types = array( + 'ERRMSG_ARR' => 'errors', + 'messages' => 'messages', + 'info' => 'info', + ); + + $data = array(); + foreach ($types as $session_var=>$smarty_var) { + if (!empty($_SESSION[$session_var])) { + $this->view->assign($smarty_var, $_SESSION[$session_var]); + $data[$session_var] = $_SESSION[$session_var]; + unset($_SESSION[$session_var]); + } } - if (!empty($_SESSION['info'])) { - $this->view->assign('info', $_SESSION['info']); - unset($_SESSION['info']); + + $response = $next($request, $response); + + // not normal page, put all flash messages back to session + if (!$response->isOk()) { + foreach ($types as $session_var=>$smarty_var) { + if (!empty($data[$session_var])) { + $new_data = !empty($_SESSION[$session_var]) ? $_SESSION[$session_var] : array(); + $smarty_data = empty($this->view->tpl_vars[$smarty_var]->value) ? array() : $this->view->tpl_vars[$smarty_var]->value; + $_SESSION[$session_var] = array_merge($new_data, $smarty_data, $data[$session_var]); + } + } } - return $next($request, $response); + return $response; }); From 83ac488d18ab6fc863468c76f0bb4bc0238de8d3 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Wed, 31 May 2017 22:50:39 +0300 Subject: [PATCH 12/43] refactored project edit and view pages --- controllers/ProjectController.php | 160 ++++++++++++++++++- include/include_proj_show.php | 144 ----------------- include/include_proj_show_price.php | 30 ---- include/include_proj_update.php | 25 --- include/routes.php | 3 + proj_edit.php | 74 --------- proj_show.php | 232 ---------------------------- views/project-edit.tpl | 26 ++++ views/project-view.tpl | 96 ++++++++++++ 9 files changed, 282 insertions(+), 508 deletions(-) delete mode 100644 include/include_proj_show.php delete mode 100644 include/include_proj_show_price.php delete mode 100644 include/include_proj_update.php delete mode 100644 proj_edit.php delete mode 100644 proj_show.php create mode 100644 views/project-edit.tpl create mode 100644 views/project-view.tpl diff --git a/controllers/ProjectController.php b/controllers/ProjectController.php index 473fca8..b0790de 100644 --- a/controllers/ProjectController.php +++ b/controllers/ProjectController.php @@ -4,6 +4,153 @@ class ProjectController extends BaseController { + public function view(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + $owner = !empty($_SESSION['SESS_MEMBER_ID']) ? $_SESSION['SESS_MEMBER_ID'] : null; + $id = (int) $args['id']; + $order = $req->getParam('order'); + if (!in_array($order, array('asc', 'desc'))) { + $order = 'asc'; + } + + $by_map = array( + 'name' => 'd.name', + 'category' => "c.name {$order}, sc.subcategory", + 'manufacturer' => 'manufacturer', + 'package' => 'package', + 'smd' => 'smd', + 'price' => 'price', + 'stock_quantity' => 'quantity', + 'order_quantity' => 'order_quantity', + 'quantity' => 'projects_data_quantity', + 'bin_location' => '', // ? + ); + $by = $req->getParam('by', 'name'); + if (!array_key_exists($by, $by_map)) { + $by = 'name'; + } + + $data = $this->getProject($id, $owner); + + if (!$data) { + return $response->withRedirect('proj_list'); + } + + $this->view->assign('project', $data); + + $sql = "SELECT pd.* + , d.* + , sc.name as subcategory + , c.name as category + FROM projects_data pd + JOIN data d ON pd.projects_data_component_id = d.id + JOIN category_sub sc ON d.category = sc.id + JOIN category_head c ON c.id = floor(sc.id / 100) + WHERE pd.projects_data_project_id = ? ORDER BY {$by_map[$by]} {$order}"; + $components = $this->db->fetchAll($sql, array( + $id, + )); + $this->view->assign('components', $components); + + // TODO: improve this weird query + $sql = 'SELECT sum(project_total.total) as total + , m.currency + FROM (SELECT cast(cast(price as decimal(14, 3)) * projects_data_quantity as decimal(14, 2)) AS total + FROM projects_data + JOIN `data` + WHERE data.id = projects_data_component_id + AND projects_data_project_id = ?) AS project_total + , projects p + JOIN members m ON m.member_id = p.project_owner + where p.project_id = ? + group by m.currency'; + $sum = $this->db->fetchAssoc($sql, array($id, $id)); + $this->view->assign('price', $sum); + + $this->view->assign('selected_menu', 'projects'); + + return $this->view->display('project-view.tpl'); + } + + private function getProject($id, $owner_id) { + $sql = 'SELECT * FROM projects WHERE project_id = ? AND project_owner = ?'; + return $this->db->fetchAssoc($sql, array( + $id, + $owner_id, + )); + } + + public function edit(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + $owner = $_SESSION['SESS_MEMBER_ID']; + $id = (int) $args['id']; + + if ($req->isPost() && $req->getParam('delete', false) === false) { + $name = $req->getParam('name'); + $public = (int) $req->getParam('project_public'); + $url = $req->getParam('project_url'); + $description = $req->getParam('project_desc'); + + if (!$name) { + $_SESSION['ERRMSG_ARR'][] = 'Project name missing'; + } + } else if ($req->isPost() && $req->getParam('delete', false) !== false) { + $deleted = $this->db->delete('projects', array( + 'project_id' => $id, + 'project_owner' => $owner, + )); + if ($deleted) { + $_SESSION['messages'][] = 'Project deleted'; + return $this->redirect($response, 'projects'); + } else { + $_SESSION['ERRMSG_ARR'][] = 'Unable to delete project'; + return $this->redirect($response, 'project_edit', array( + 'id' => $id, + )); + } + } + + $data = $this->getProject($id, $owner); + + if (!$data) { + $_SESSION['ERRMSG_ARR'][] = 'Project not found'; + return $response->withRedirect('proj_list'); + } + + if ($req->isPost() && !empty($_SESSION['ERRMSG_ARR'])) { + if (!empty($name)) { + $data['project_name'] = $name; + } + if (isset($public)) { + $data['project_public'] = $public; + } + if (isset($url)) { + $data['project_url'] = $url; + } + if (isset($description)) { + $data['project_desc'] = $description; + } + } + + if ($req->isPost() && empty($_SESSION['ERRMSG_ARR'])) { + $this->db->update('projects', array( + 'project_name' => $name, + 'project_public' => $public, + 'project_url' => $url, + 'project_desc' => $description, + ), array( + 'project_id' => $id, + )); + $_SESSION['messages'][] = 'Project saved'; + return $this->redirect($response, 'project_edit', array('id'=>$id)); + } + + $this->view->assign('project', $data); + $this->view->assign('selected_menu', 'projects'); + + return $this->render('project-edit.tpl'); + } + public function add(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { $owner = $_SESSION['SESS_MEMBER_ID']; @@ -22,9 +169,16 @@ public function add(\Slim\Http\Request $req, \Slim\Http\Response $response, $arg 'project_name' => $name, )); - $_SESSION['messages'] = array( - 'Project added!', - ); + if ($added) { + $_SESSION['messages'] = array( + 'Project added!', + ); + return $this->redirect($response, 'project_edit', array( + 'id' => $this->db->lastInsertId(), + )); + } else { + $_SESSION['ERRMSG_ARR'][] = 'Error creating new project'; + } return $this->redirect($response, 'projects'); } diff --git a/include/include_proj_show.php b/include/include_proj_show.php deleted file mode 100644 index 42b85d3..0000000 --- a/include/include_proj_show.php +++ /dev/null @@ -1,144 +0,0 @@ -"; - - echo ''; - - echo ''; - - echo $showDetails['name']; - echo ""; - - echo ""; - - if ($showDetails['category'] < 999) { - $head_cat_id = substr($showDetails['category'], -3, 1); - } - else { - $head_cat_id = substr($showDetails['category'], -4, 2); - } - $subcatid = $showDetails['category']; - - $CategoryName = "SELECT * FROM category_head WHERE id = ".$head_cat_id.""; - $sql_exec_catname = mysql_Query($CategoryName); - - while($showDetailsCat = mysql_fetch_array($sql_exec_catname)) { - $catname = $showDetailsCat['name']; - } - - echo $catname; - echo ""; - - echo ""; - $manufacturer = $showDetails['manufacturer']; - if ($manufacturer == ""){ - echo "-"; - } - else{ - echo $manufacturer; - } - echo ""; - - echo ""; - $package = $showDetails['package']; - if ($package == ""){ - echo "-"; - } - else{ - echo $package; - } - echo ""; - - echo ""; - $smd = $showDetails['smd']; - if ($smd == "No"){ - echo ''; - } - else{ - echo ''; - } - echo ""; - - echo ""; - $price = $showDetails['price']; - if ($price == ""){ - echo "-"; - } - else{ - echo $price; - } - echo ""; - - echo ""; - $quantity = $showDetails['quantity']; - if ($quantity == ""){ - echo "-"; - } - else{ - echo $quantity; - } - echo ""; - - echo ""; - - $comp_id = $showDetails['id']; - $ShowQuant = mysql_query("SELECT projects_data_quantity FROM projects_data WHERE projects_data_component_id = '$comp_id' AND projects_data_project_id = '$project_id'"); - $quant = mysql_fetch_assoc($ShowQuant); - - $quantity = $quant['projects_data_quantity']; - if ($quantity == ""){ - echo "-"; - } - else{ - echo $quantity; - } - - - echo ""; - - echo ""; - } - } -} -?> diff --git a/include/include_proj_show_price.php b/include/include_proj_show_price.php deleted file mode 100644 index dbdbe9b..0000000 --- a/include/include_proj_show_price.php +++ /dev/null @@ -1,30 +0,0 @@ - \ No newline at end of file diff --git a/include/include_proj_update.php b/include/include_proj_update.php deleted file mode 100644 index 2a95833..0000000 --- a/include/include_proj_update.php +++ /dev/null @@ -1,25 +0,0 @@ - \ No newline at end of file diff --git a/include/routes.php b/include/routes.php index b18e4b4..f4f1666 100644 --- a/include/routes.php +++ b/include/routes.php @@ -17,6 +17,9 @@ $app->get('/about', 'AboutController:index')->setName('about'); $app->get('/proj_list', 'ProjectController:projects')->setName('projects'); $app->post('/project_add', 'ProjectController:add')->setName('project_add'); +$app->get('/project/{id}/edit', 'ProjectController:edit')->setName('project_edit'); +$app->post('/project/{id}/edit', 'ProjectController:edit'); +$app->get('/project/{id}', 'ProjectController:view')->setName('project'); // redirect to php file $app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { diff --git a/proj_edit.php b/proj_edit.php deleted file mode 100644 index cbbf276..0000000 --- a/proj_edit.php +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - Your Projects - ecDB - - - - - -
    - - - - - - - - - - -
    -

    Edit Project

    - - AddProj(); - ?> - - -
    - -
    -
    -
    -
    - - -
    -
    - -
    - - - - -
    - - \ No newline at end of file diff --git a/proj_show.php b/proj_show.php deleted file mode 100644 index c173012..0000000 --- a/proj_show.php +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - "/> - - - - Viewing project - <?php - // Visar projektets namn. - include('include/mysql_connect.php'); - $project_id = mysql_real_escape_string($_GET["proj_id"]); - $owner = $_SESSION['SESS_MEMBER_ID']; - - $result = mysql_query("SELECT project_name FROM projects WHERE project_owner = ".$owner." AND project_id = ".$project_id.""); - - while($row = mysql_fetch_array($result)) - { - echo $row['project_name']; - } - ?> - ecDB - - - - -
    - - - - - - - -
    -

    Viewing project - "; - echo $row['project_name']; - echo ""; - } - ?> -

    - - - - - - - - - - - - - - - - - ProjectShowComponents(); - ?> - -
    - Name - - Category - - Manufacturer - - Package - - SMD - - Price - - Quantity in stock - - Quantity in project -
    - -
    - ProjectSumTotal(); - ?> -
    -
    - - - - -
    - - diff --git a/views/project-edit.tpl b/views/project-edit.tpl new file mode 100644 index 0000000..e6f30a4 --- /dev/null +++ b/views/project-edit.tpl @@ -0,0 +1,26 @@ +{extends file='layout.tpl'} + +{block name=title}Your Projects - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + + +

    Edit Project

    + +
    +
    + +
    +
    + +
    +
    + + +
    +
    +
    + +{/block} \ No newline at end of file diff --git a/views/project-view.tpl b/views/project-view.tpl new file mode 100644 index 0000000..f305eba --- /dev/null +++ b/views/project-view.tpl @@ -0,0 +1,96 @@ +{extends file='layout.tpl'} + +{block name=title}Viewing project - {$project.project_name} - ecDB{/block} + +{block name=head} + + + + +{/block} + +{block name=body} +

    + Viewing project + + {if $project.project_url} + {$project.project_name} + {else} + {$project.project_name} + {/if} + +

    + + + + + + + + + + + + + + + + + {foreach from=$components item=component} + + {if $smarty.session.SESS_MEMBER_ID} + + + {else} + + + {/if} + + + + + + + + + {/foreach} + +
    + Name + + Category + + Manufacturer + + Package + + SMD + + Price + + Quantity in stock + + Quantity in project +
    + + + {$component.name} + {$component.name}{$component.category} / {$component.subcategory}{if $component.manufacturer}{$component.manufacturer}{else}-{/if}{if $component.package}{$component.package}{else}-{/if}{if $component.price}{$component.price}{else}-{/if}{if $component.quantity}{$component.quantity}{else}-{/if}{if $component.projects_data_quantity}{$component.projects_data_quantity}{else}-{/if}
    + +
    + {if !$price.total} + 0 {$price.currency} + {else} + {$price.total} {$price.currency} + {/if} +
    +{/block} From e8951114a35840de6e099d00396cd0be587fbe39 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Thu, 1 Jun 2017 19:03:02 +0300 Subject: [PATCH 13/43] add middleware that controls what pages are accessible by non-members --- include/middlewares.php | 43 +++++++++++++++++++++++++++++++++++++++++ include/routes.php | 10 +++++----- index.php | 6 +++++- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/include/middlewares.php b/include/middlewares.php index 89611a5..8119a1b 100644 --- a/include/middlewares.php +++ b/include/middlewares.php @@ -35,3 +35,46 @@ return $response; }); + +$app->add(function ($request, $response, $next) { + $route = $request->getAttribute('route'); + + // index for non existent route + if (empty($route)) { + $path = $this->get('router')->pathFor('index'); + return $response->withRedirect($path); + } + + $name = $route->getName(); + # $groups = $route->getGroups(); + # $methods = $route->getMethods(); + # $arguments = $route->getArguments(); + + $public_route_names = array( + 'login', + 'register', + 'about', + 'auth', + 'terms', + 'contact', + 'donate', + 'project_bom_download', + ); + + if (empty($_SESSION['SESS_MEMBER_ID']) && !in_array($name, $public_route_names)) { + $path = $this->get('router')->pathFor('login'); + return $response->withRedirect($path); + } + + $admin_route_names = array( + 'admin', + 'admin_users', + ); + + if ((empty($_SESSION['SESS_MEMBER_ID']) || empty($_SESSION['SESS_IS_ADMIN'])) && in_array($name, $admin_route_names)) { + $path = $this->get('router')->pathFor('login'); + return $response->withRedirect($path); + } + + return $next($request, $response); +}); diff --git a/include/routes.php b/include/routes.php index f4f1666..24443d1 100644 --- a/include/routes.php +++ b/include/routes.php @@ -3,22 +3,22 @@ // index $app->any('/', function ($request, $response, $args) { require_once(__DIR__ . '/../index_page.php'); -}); +})->setName('index'); $app->any('/index.php', function ($request, $response, $args) { require_once(__DIR__ . '/../index_page.php'); -}); +})->setName('index'); // login/logout -$app->get('/login', 'LoginController:index')->setName('index'); +$app->get('/login', 'LoginController:index')->setName('login'); $app->post('/auth', 'LoginController:auth')->setName('auth'); $app->get('/logout', 'LoginController:logout')->setName('logout'); $app->get('/register', 'RegisterController:index')->setName('register'); -$app->post('/register', 'RegisterController:register'); +$app->post('/register', 'RegisterController:register')->setName('register'); $app->get('/about', 'AboutController:index')->setName('about'); $app->get('/proj_list', 'ProjectController:projects')->setName('projects'); $app->post('/project_add', 'ProjectController:add')->setName('project_add'); $app->get('/project/{id}/edit', 'ProjectController:edit')->setName('project_edit'); -$app->post('/project/{id}/edit', 'ProjectController:edit'); +$app->post('/project/{id}/edit', 'ProjectController:edit')->setName('project_edit'); $app->get('/project/{id}', 'ProjectController:view')->setName('project'); // redirect to php file diff --git a/index.php b/index.php index 4738bed..3632ed9 100644 --- a/index.php +++ b/index.php @@ -2,7 +2,11 @@ require_once __DIR__ . '/setup.php'; -$app = new \Slim\App(new \Slim\Container); +$app = new \Slim\App(array( + 'settings' => array( + 'determineRouteBeforeAppMiddleware' => true, + ), +)); require_once __DIR__ . '/include/dependencies.php'; require_once __DIR__ . '/include/middlewares.php'; From ee780f69b9ef1d836c80ed52e11e1bb41c3835bf Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Thu, 1 Jun 2017 23:40:03 +0300 Subject: [PATCH 14/43] added controllers for terms, contacts and donation pages and refactored views --- contact.php | 54 --------------------- controllers/ContactController.php | 12 +++++ controllers/DonateController.php | 13 ++++++ controllers/TermsController.php | 12 +++++ donate.php | 71 ---------------------------- include/dependencies.php | 9 ++++ include/footer.php | 2 +- include/middlewares.php | 6 +-- include/routes.php | 3 ++ terms.php | 78 ------------------------------- views/contact.tpl | 13 ++++++ views/donate.tpl | 21 +++++++++ views/layout.tpl | 6 +-- views/registration.tpl | 2 +- views/terms.tpl | 41 ++++++++++++++++ 15 files changed, 132 insertions(+), 211 deletions(-) delete mode 100644 contact.php create mode 100644 controllers/ContactController.php create mode 100644 controllers/DonateController.php create mode 100644 controllers/TermsController.php delete mode 100644 donate.php delete mode 100644 terms.php create mode 100644 views/contact.tpl create mode 100644 views/donate.tpl create mode 100644 views/terms.tpl diff --git a/contact.php b/contact.php deleted file mode 100644 index edf400c..0000000 --- a/contact.php +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - Contact - ecDB - - - - -
    - '; - include 'include/header.php'; - echo ''; - - echo ''; - include 'include/menu.php'; - echo ''; - } - else { - echo ''; - include 'include/header_public.php'; - echo ''; - - echo ''; - include 'include/menu_public.php'; - echo ''; - } - ?> - -
    -
    -
    -

    Contact us

    - If you have any suggestions, questions or what not. Send us an email to info@ecdb.net -
    -
    -
    -
    - - - - -
    - - \ No newline at end of file diff --git a/controllers/ContactController.php b/controllers/ContactController.php new file mode 100644 index 0000000..9e82559 --- /dev/null +++ b/controllers/ContactController.php @@ -0,0 +1,12 @@ +view->display('contact.tpl'); + } + +} + diff --git a/controllers/DonateController.php b/controllers/DonateController.php new file mode 100644 index 0000000..4c974c7 --- /dev/null +++ b/controllers/DonateController.php @@ -0,0 +1,13 @@ +view->assign('selected_menu', 'donate'); + return $this->view->display('donate.tpl'); + } + +} + diff --git a/controllers/TermsController.php b/controllers/TermsController.php new file mode 100644 index 0000000..04a3661 --- /dev/null +++ b/controllers/TermsController.php @@ -0,0 +1,12 @@ +view->display('terms.tpl'); + } + +} + diff --git a/donate.php b/donate.php deleted file mode 100644 index 6f61235..0000000 --- a/donate.php +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - Contact - ecDB - - - - -
    - '; - include 'include/header.php'; - echo ''; - - echo ''; - include 'include/menu.php'; - echo ''; - } - else { - echo ''; - echo ''; - echo ''; - - echo ''; - echo ''; - echo ''; - } - ?> - -
    -
    -
    -

    Donate

    - ecDB is completely free!
    - However, if you like ecDB you may use the button below to donate some money to the project!

    -
    - - - -
    -
    -
    -
    -
    - - - - -
    - - \ No newline at end of file diff --git a/include/dependencies.php b/include/dependencies.php index d4ccc0c..2fabccc 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -15,6 +15,15 @@ $container['ProjectController'] = function ($container) use ($app) { return new \Ecdb\Controllers\ProjectController($app); }; +$container['TermsController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\TermsController($app); +}; +$container['ContactController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\ContactController($app); +}; +$container['DonateController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\DonateController($app); +}; $container['view'] = function ($container) use ($ECDB_VERSION) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); diff --git a/include/footer.php b/include/footer.php index ff30c92..8ad3a1c 100644 --- a/include/footer.php +++ b/include/footer.php @@ -1,6 +1,6 @@
    -
    © 2010 - ecDB - Created by Nils Fredriksson - Contact us - Terms & Privacy
    +
    © 2010 - ecDB - Created by Nils Fredriksson - Contact us - Terms & Privacy
    diff --git a/include/middlewares.php b/include/middlewares.php index 8119a1b..7727a9e 100644 --- a/include/middlewares.php +++ b/include/middlewares.php @@ -54,11 +54,12 @@ 'login', 'register', 'about', + 'projects', 'auth', 'terms', 'contact', 'donate', - 'project_bom_download', + 'project', ); if (empty($_SESSION['SESS_MEMBER_ID']) && !in_array($name, $public_route_names)) { @@ -67,8 +68,7 @@ } $admin_route_names = array( - 'admin', - 'admin_users', + ); if ((empty($_SESSION['SESS_MEMBER_ID']) || empty($_SESSION['SESS_IS_ADMIN'])) && in_array($name, $admin_route_names)) { diff --git a/include/routes.php b/include/routes.php index 24443d1..5dc42d0 100644 --- a/include/routes.php +++ b/include/routes.php @@ -20,6 +20,9 @@ $app->get('/project/{id}/edit', 'ProjectController:edit')->setName('project_edit'); $app->post('/project/{id}/edit', 'ProjectController:edit')->setName('project_edit'); $app->get('/project/{id}', 'ProjectController:view')->setName('project'); +$app->get('/terms', 'TermsController:index')->setName('terms'); +$app->get('/contact', 'ContactController:index')->setName('contact'); +$app->get('/donate', 'DonateController:index')->setName('donate'); // redirect to php file $app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { diff --git a/terms.php b/terms.php deleted file mode 100644 index 6168f8e..0000000 --- a/terms.php +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - Terms & Privacy - ecDB - - - -
    - '; - include 'include/header.php'; - echo ''; - - echo ''; - include 'include/menu.php'; - echo ''; - } - else { - echo ''; - include 'include/header_public.php'; - echo ''; - - echo ''; - include 'include/menu_public.php'; - echo ''; - } - ?> - -
    -

    Terms and Conditions & Privacy Policy

    - -

    1. Terms

    - - By accessing this web site, you are agreeing to be bound by these web site Terms and Conditions of Use, all applicable laws and regulations, and agree that you are responsible for compliance with any applicable local laws. If you do not agree with any of these terms, you are prohibited from using or accessing this site. The materials contained in this web site are protected by applicable copyright and trademark law.

    - -

    2. Membership

    - - As a condition to using the services you are required to register with ecDB. By registering with ecDB you certify that you always provide valid, and updated information, you are an individual (i.e., not a corporate entity) and that you have the legal rights to enter such an agreement. The ID and password (from now referred to as "login-data") is the sole responsibility. It is required that you, as a registered ecDB user maintain the safety of your own login-data.

    - - ecDB maintains the right to terminate your membership at any time, with or without motivation or warning. All members are responsible for the consequences of use of this website. In cases of conflict with one or more non-members or members, will ecDB not be liable for any damages caused, in the current situation or future, resulting from the conflict.

    - - As a registered ecDB user you warrant and agree to the fact that you will not contribute any content that (a) infringes, violates or otherwise interferes with any copyright or trademark of another party, (b) reveal any trade secret, unless you own the trade secret or has the owner’s permission to post it, (c) infringes any intellectual property right of another or the privacy or publicity rights of another, (d) is libelous, defamatory, abusive, threatening, harassing, hateful, offensive or otherwise violates any law or right of any third party.

    - -

    3. Disclaimer

    - - ecDB reserves all rights and disclaims all liability. ecDB makes no guarantee of reliability, safety or operation of this site.
    - As a registered user, you have full responsibility, without contradiction, for the information you publish and make widely available here.

    - -

    4. Ownership

    - - It is strictly forbidden to copy, distribute, or modify any material from ecDB. You may print material for private use. For all other use requires permission from ecDB.

    - -

    5. Site Terms of Use Modifications

    - - ecDB may revise these terms of use at any time without notice. By using ecDB you are agreeing to be bound by the then current version of these Terms and Conditions of Use.

    - -

    Privacy Policy

    - - ecDB handles your personal information in accordance with the European data protection laws.

    - - Third parties can get access to all the information you intended to make public through your settings. Your email address or other personal data is NEVER shared by us to third parties. -
    - - - - -
    - - diff --git a/views/contact.tpl b/views/contact.tpl new file mode 100644 index 0000000..b508880 --- /dev/null +++ b/views/contact.tpl @@ -0,0 +1,13 @@ +{extends file='layout.tpl'} + +{block name=title}Contact - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + +

    Contact us

    + + If you have any suggestions, questions or what not. Contact through the ecDB GitHub Project. + +{/block} \ No newline at end of file diff --git a/views/donate.tpl b/views/donate.tpl new file mode 100644 index 0000000..2af0f9b --- /dev/null +++ b/views/donate.tpl @@ -0,0 +1,21 @@ +{extends file='layout.tpl'} + +{block name=title}Donate - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + +

    Donate

    + + ecDB is completely free!
    + + However, if you like ecDB you may use the button below to donate some money to the project!

    + +
    + + + +
    + +{/block} \ No newline at end of file diff --git a/views/layout.tpl b/views/layout.tpl index 2a16741..ca30ec7 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -44,7 +44,7 @@
  • Projects
  • My account
  • Public components
  • - + {/if} {if !$smarty.session.SESS_MEMBER_ID}
  • Login
  • @@ -87,8 +87,8 @@
    © 2010 - {'Y'|@date} ecDB - Created by Nils Fredriksson - - Contact us - - Terms & Privacy + - Contact us + - Terms & Privacy - About
    {if $smarty.session.SESS_IS_ADMIN} diff --git a/views/registration.tpl b/views/registration.tpl index 7709210..5feafda 100644 --- a/views/registration.tpl +++ b/views/registration.tpl @@ -42,7 +42,7 @@
    - By registering you accept the Terms and Contidions.

    + By registering you accept the Terms and Contidions.

    diff --git a/views/terms.tpl b/views/terms.tpl new file mode 100644 index 0000000..454f6f2 --- /dev/null +++ b/views/terms.tpl @@ -0,0 +1,41 @@ +{extends file='layout.tpl'} + +{block name=title}Terms & Privacy - ecDB{/block} + +{block name=head}{/block} + +{block name=body} +

    Terms and Conditions & Privacy Policy

    + +

    1. Terms

    + + By accessing this web site, you are agreeing to be bound by these web site Terms and Conditions of Use, all applicable laws and regulations, and agree that you are responsible for compliance with any applicable local laws. If you do not agree with any of these terms, you are prohibited from using or accessing this site. The materials contained in this web site are protected by applicable copyright and trademark law.

    + +

    2. Membership

    + + As a condition to using the services you are required to register with ecDB. By registering with ecDB you certify that you always provide valid, and updated information, you are an individual (i.e., not a corporate entity) and that you have the legal rights to enter such an agreement. The ID and password (from now referred to as "login-data") is the sole responsibility. It is required that you, as a registered ecDB user maintain the safety of your own login-data.

    + + ecDB maintains the right to terminate your membership at any time, with or without motivation or warning. All members are responsible for the consequences of use of this website. In cases of conflict with one or more non-members or members, will ecDB not be liable for any damages caused, in the current situation or future, resulting from the conflict.

    + + As a registered ecDB user you warrant and agree to the fact that you will not contribute any content that (a) infringes, violates or otherwise interferes with any copyright or trademark of another party, (b) reveal any trade secret, unless you own the trade secret or has the owner’s permission to post it, (c) infringes any intellectual property right of another or the privacy or publicity rights of another, (d) is libelous, defamatory, abusive, threatening, harassing, hateful, offensive or otherwise violates any law or right of any third party.

    + +

    3. Disclaimer

    + + ecDB reserves all rights and disclaims all liability. ecDB makes no guarantee of reliability, safety or operation of this site.
    + As a registered user, you have full responsibility, without contradiction, for the information you publish and make widely available here.

    + +

    4. Ownership

    + + It is strictly forbidden to copy, distribute, or modify any material from ecDB. You may print material for private use. For all other use requires permission from ecDB.

    + +

    5. Site Terms of Use Modifications

    + + ecDB may revise these terms of use at any time without notice. By using ecDB you are agreeing to be bound by the then current version of these Terms and Conditions of Use.

    + +

    Privacy Policy

    + + ecDB handles your personal information in accordance with the European data protection laws.

    + + Third parties can get access to all the information you intended to make public through your settings. Your email address or other personal data is NEVER shared by us to third parties. + +{/block} \ No newline at end of file From 2d8cb4b9ed17532d06f1d313c6697b70a4d9a99c Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Thu, 1 Jun 2017 23:41:04 +0300 Subject: [PATCH 15/43] require Parsedown with composer --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index b20f952..1c48489 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,7 @@ }, "require": { "doctrine/dbal": "*", + "erusev/parsedown": "*", "slim/slim": "^3.8", "smarty/smarty": "^3.1" } From f7324512f7194cc849bd1160315d37043b311d61 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Thu, 1 Jun 2017 23:43:24 +0300 Subject: [PATCH 16/43] added members controller and refactored members page --- controllers/MemberController.php | 101 ++++++++ include/dependencies.php | 3 + include/header.php | 2 +- include/include_my_settings.php | 96 ------- include/menu.php | 2 +- include/routes.php | 2 + my.php | 428 ------------------------------- views/layout.tpl | 4 +- views/member.tpl | 73 ++++++ 9 files changed, 183 insertions(+), 528 deletions(-) create mode 100644 controllers/MemberController.php delete mode 100644 include/include_my_settings.php delete mode 100644 my.php create mode 100644 views/member.tpl diff --git a/controllers/MemberController.php b/controllers/MemberController.php new file mode 100644 index 0000000..95df13f --- /dev/null +++ b/controllers/MemberController.php @@ -0,0 +1,101 @@ +db->fetchAssoc('SELECT COUNT(*) AS c FROM members WHERE member_id = ? AND passwd = ?', array( + $member_id, + md5($password), + )); + + return !empty($data['c']); + } + + public function edit(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + + if($req->isPost()) { + $owner = $_SESSION['SESS_MEMBER_ID']; + $firstname = $req->getParam('firstname'); + $lastname = $req->getParam('lastname'); + $mail = $req->getParam('mail'); + $measurement = (int) $req->getParam('measurement'); + $currency = $req->getParam('currency'); + $oldpass = $req->getParam('oldpass'); + $newpass = $req->getParam('newpass'); + + if (!in_array($currency, array('SEK', 'USD', 'EUR', 'GBP'))) { + $currency = 'SEK'; + } + + if (!$firstname) { + $_SESSION['ERRMSG_ARR'][] = 'First name missing'; + } else if (strlen($firstname) < 2) { + $_SESSION['ERRMSG_ARR'][] = 'Minimum of 2 chars in first name.'; + } + + if (!$lastname) { + $_SESSION['ERRMSG_ARR'][] = 'Last name missing'; + } else if (strlen($lastname) < 2) { + $_SESSION['ERRMSG_ARR'][] = 'Minimum of 2 chars in last name.'; + } + + if (!$mail) { + $_SESSION['ERRMSG_ARR'][] = 'Mail missing'; + } else if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) { + $_SESSION['ERRMSG_ARR'][] = 'Invalid e-mail address'; + } + + if (!$oldpass && $newpass) { + $_SESSION['ERRMSG_ARR'][] = 'For setting new password, please provide current password'; + } else if ($oldpass && !$newpass && strlen($newpass) < 5) { + $_SESSION['ERRMSG_ARR'][] = 'Minimum of 5 chars in password'; + } else if ($oldpass && !$this->inPasswordValid($owner, $oldpass)) { + $_SESSION['ERRMSG_ARR'][] = 'Provided current password is incorrect'; + } + + if (empty($_SESSION['ERRMSG_ARR'])) { + $data = array( + 'firstname' => $firstname, + 'lastname' => $lastname, + 'mail' => $mail, + 'passwd' => md5($newpass), + 'measurement' => $measurement, + 'currency' => $currency, + ); + if ($oldpass && $newpass) { + $data['passwd'] = md5($newpass); + } + $this->db->update('members', $data, array( + 'member_id' => $owner, + )); + $_SESSION['messages'][] = 'Settings updated'; + return $this->redirect($response, 'my'); + } + } + + $data = $this->db->fetchAssoc('SELECT * FROM members WHERE member_id = ?', array( + $_SESSION['SESS_MEMBER_ID'] + )); + + unset($data['passwd']); + + if ($req->isPost()) { + $data['firstname'] = $firstname; + $data['lastname'] = $lastname; + $data['mail'] = $mail; + $data['measurement'] = $measurement; + $data['currency'] = $currency; + } + + $this->view->assign('member', $data); + + $this->view->assign('selected_menu', 'my'); + + return $this->view->display('member.tpl'); + } + +} + diff --git a/include/dependencies.php b/include/dependencies.php index 2fabccc..eca703d 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -15,6 +15,9 @@ $container['ProjectController'] = function ($container) use ($app) { return new \Ecdb\Controllers\ProjectController($app); }; +$container['MemberController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\MemberController($app); +}; $container['TermsController'] = function ($container) use ($app) { return new \Ecdb\Controllers\TermsController($app); }; diff --git a/include/header.php b/include/header.php index 376173a..019ddd4 100644 --- a/include/header.php +++ b/include/header.php @@ -5,7 +5,7 @@
    - Logged in as + Logged in as '; - echo 'First name missing'; - echo '
    '; - } - elseif (strlen($firstname) <= 2) { - echo '
    '; - echo 'Minimum of 2 chars in first name.'; - echo '
    '; - } - elseif ($lastname == '') { - echo '
    '; - echo 'Last name missing'; - echo '
    '; - } - elseif (strlen($lastname) <= 2) { - echo '
    '; - echo 'Minimum of 2 chars in last name.'; - echo '
    '; - } - elseif ($mail == '') { - echo '
    '; - echo 'Mail missing'; - echo '
    '; - } - elseif (!filter_var($mail, FILTER_VALIDATE_EMAIL)) { - echo '
    '; - echo 'Invalid e-mail address'; - echo '
    '; - } - elseif (!empty($oldpass) && !empty($newpass) && $owner == 4) { - echo '
    '; - echo 'Y NO CHANGE PASSWORD FOR THE DEMO ACCOUNT!!11'; - echo '
    '; - } - elseif (!empty($oldpass) && !empty($newpass) && $oldpass == '') { - echo '
    '; - echo 'Password missing'; - echo '
    '; - } - elseif (!empty($oldpass) && !empty($newpass) && $newpass == '') { - echo '
    '; - echo 'Confirm password missing'; - echo '
    '; - } - elseif (!empty($oldpass) && !empty($newpass) && strlen($newpass) <= 5) { - echo '
    '; - echo 'Minimum of 5 chars in password.'; - echo '
    '; - } - elseif (!empty($oldpass) && !empty($newpass) && strcmp(md5($oldpass), $executesql['passwd']) != 0 ) { - echo '
    '; - echo 'The password is invalid '; - echo '
    '; - } - else { - if (!empty($oldpass) && !empty($newpass)) { - $sql="UPDATE members SET firstname = '$firstname', lastname = '$lastname', mail = '$mail', passwd = '".md5($newpass)."', measurement = '$measurement', currency = '$currency' WHERE member_id = '$owner'"; - $sql_exec = mysql_query($sql); - } - else { - $sql="UPDATE members SET firstname = '$firstname', lastname = '$lastname', mail = '$mail', measurement = '$measurement', currency = '$currency' WHERE member_id = '$owner'"; - $sql_exec = mysql_query($sql); - } - - echo '
    '; - echo 'Settings updated!'; - echo '
    '; - } - } - } -} -?> \ No newline at end of file diff --git a/include/menu.php b/include/menu.php index f65b4ee..7d1631a 100644 --- a/include/menu.php +++ b/include/menu.php @@ -4,7 +4,7 @@
  • "> Add component
  • "> Shopping list
  • "> Projects
  • -
  • "> My account
  • +
  • "> My account
  • "> Public components
  • diff --git a/include/routes.php b/include/routes.php index 5dc42d0..724e4c9 100644 --- a/include/routes.php +++ b/include/routes.php @@ -20,6 +20,8 @@ $app->get('/project/{id}/edit', 'ProjectController:edit')->setName('project_edit'); $app->post('/project/{id}/edit', 'ProjectController:edit')->setName('project_edit'); $app->get('/project/{id}', 'ProjectController:view')->setName('project'); +$app->get('/my', 'MemberController:edit')->setName('member_edit'); +$app->post('/my', 'MemberController:edit')->setName('member_edit'); $app->get('/terms', 'TermsController:index')->setName('terms'); $app->get('/contact', 'ContactController:index')->setName('contact'); $app->get('/donate', 'DonateController:index')->setName('donate'); diff --git a/my.php b/my.php deleted file mode 100644 index 47eee32..0000000 --- a/my.php +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - - - Home - ecDB - - - - - -
    - - - - - - - - - - -
    -

    Settings

    - - Settings(); - ?> - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - First Name - - - - Last Name - - -
    - Email - - -
    - Password - - - - New password - - -
    - Measurement System - - Metric '; - echo ' Retarded American System (Imperial)'; - } - if(!isset($_POST['submit']) && $executesql['measurement'] == 0) { - echo ' Metric '; - echo ' Retarded American System (Imperial)'; - } - if(isset($_POST['submit']) && $_POST['measurement'] == 1) { - echo ' Metric '; - echo ' Retarded American System (Imperial)'; - } - if(isset($_POST['submit']) && $_POST['measurement'] == 0) { - echo ' Metric '; - echo ' Retarded American System (Imperial)'; - } - ?> -
    - Currency - - -
    -
    -
    - -
    -
    -
    -
    - - - - -
    - - diff --git a/views/layout.tpl b/views/layout.tpl index ca30ec7..85162cd 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -21,7 +21,7 @@ {if $smarty.session.SESS_MEMBER_ID} Logged in as - + {$smarty.session.SESS_FIRST_NAME} {$smarty.session.SESS_LAST_NAME} - @@ -42,7 +42,7 @@
  • Add component
  • Shopping list
  • Projects
  • -
  • My account
  • +
  • My account
  • Public components
  • {/if} diff --git a/views/member.tpl b/views/member.tpl new file mode 100644 index 0000000..291e50e --- /dev/null +++ b/views/member.tpl @@ -0,0 +1,73 @@ +{extends file='layout.tpl'} + +{block name=title}Home - ecDB{/block} + +{block name=head}{/block} + +{block name=body} +

    Settings

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + {if $smarty.session.SESS_IS_ADMIN} + + + + + {/if} + +
    First Name + + Last Name + +
    Email + +
    Current Password + + New password + +
    Measurement System + Metric + American System (Imperial) +
    Currency + +
    Administrative User + {if $member.admin == 1}Yes{else}No{/if} +
    +
    +
    + +
    +
    +
    +{/block} \ No newline at end of file From 25e9b36b15c9acbb96c6385cb363f3be52b2c34c Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Fri, 2 Jun 2017 21:52:25 +0300 Subject: [PATCH 17/43] added shop controller and refactored shoplist page --- controllers/ShopController.php | 53 ++++++++++ include/dependencies.php | 3 + include/include_shoplist.php | 124 ----------------------- include/include_shoplist_sum.php | 36 ------- include/menu.php | 2 +- include/routes.php | 1 + shoplist.php | 167 ------------------------------- views/shop_list.tpl | 79 +++++++++++++++ 8 files changed, 137 insertions(+), 328 deletions(-) create mode 100644 controllers/ShopController.php delete mode 100644 include/include_shoplist.php delete mode 100644 include/include_shoplist_sum.php delete mode 100644 shoplist.php create mode 100644 views/shop_list.tpl diff --git a/controllers/ShopController.php b/controllers/ShopController.php new file mode 100644 index 0000000..36ffb86 --- /dev/null +++ b/controllers/ShopController.php @@ -0,0 +1,53 @@ +getParam('order'); + $order = $req->getParam('by'); + + if (!in_array($order, array('asc', 'desc'))) { + $order = 'asc'; + } + if (!array_key_exists($by, $order_fields)) { + $by = 'name'; + } + + $sql = "SELECT * FROM data WHERE owner = ? AND order_quantity > 0 ORDER by {$by} {$order}"; + $data = $this->db->fetchAll($sql, array( + $_SESSION['SESS_MEMBER_ID'], + )); + $this->view->assign('components', $data); + + $total_price = 0; + foreach ($data as $row) { + $total_price += (float) $row['price'] * (int) $row['order_quantity']; + } + $this->view->assign('total_price', $total_price); + + $sql = "SELECT currency FROM members WHERE member_id = ?"; + $currency = $this->db->fetchAssoc($sql, array( + $_SESSION['SESS_MEMBER_ID'], + )); + $this->view->assign('currency', $currency['currency']); + + $this->view->assign('selected_menu', 'shop_list'); + + return $this->view->display('shop_list.tpl'); + } + +} + diff --git a/include/dependencies.php b/include/dependencies.php index eca703d..082cb59 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -27,6 +27,9 @@ $container['DonateController'] = function ($container) use ($app) { return new \Ecdb\Controllers\DonateController($app); }; +$container['ShopController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\ShopController($app); +}; $container['view'] = function ($container) use ($ECDB_VERSION) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); diff --git a/include/include_shoplist.php b/include/include_shoplist.php deleted file mode 100644 index 9907773..0000000 --- a/include/include_shoplist.php +++ /dev/null @@ -1,124 +0,0 @@ - 0 ORDER by ".$bysql." +0 ".$ordersql.""; - } - else { - - $GetDataComponentsAll = "SELECT * FROM data WHERE owner = ".$owner." AND order_quantity > 0 ORDER by ".$bysql." ".$ordersql.""; - } - } - else { - $GetDataComponentsAll = "SELECT * FROM data WHERE owner = ".$owner." AND order_quantity > 0 ORDER by name ASC"; - } - - - $sql_exec = mysql_Query($GetDataComponentsAll); - - while($showDetails = mysql_fetch_array($sql_exec)) { - echo ""; - - echo ''; - - echo ''; - - echo $showDetails['name']; - echo ""; - - echo ""; - $manufacturer = $showDetails['manufacturer']; - if ($manufacturer == ""){ - echo "-"; - } - else{ - echo $manufacturer; - } - echo ""; - - echo ""; - $package = $showDetails['package']; - if ($package == ""){ - echo "-"; - } - else{ - echo $package; - } - echo ""; - - - echo ""; - $smd = $showDetails['smd']; - if ($smd == "No"){ - echo ''; - } - else{ - echo ''; - } - echo ""; - - echo ""; - $price = $showDetails['price']; - if ($price == ""){ - echo "-"; - } - else{ - echo $price; - } - echo ""; - - echo ""; - $quantity = $showDetails['quantity']; - if ($quantity == ""){ - echo "-"; - } - else{ - echo $quantity; - } - echo ""; - - echo ""; - $order_quantity = $showDetails['order_quantity']; - if ($order_quantity == ""){ - echo "-"; - } - else{ - echo $order_quantity; - } - echo ""; - - $comment = $showDetails['comment']; - if ($comment==""){ - echo '
    '; - echo "-"; - echo '
    '; - } - else{ - echo '
    '; - echo $showDetails['comment']; - echo '
    '; - } - echo ""; - } - } -} -?> \ No newline at end of file diff --git a/include/include_shoplist_sum.php b/include/include_shoplist_sum.php deleted file mode 100644 index 1d2b9b7..0000000 --- a/include/include_shoplist_sum.php +++ /dev/null @@ -1,36 +0,0 @@ - 0 ORDER by name ASC"; - - $sql_exec = mysql_Query($GetDataComponentsAll); - while($showDetails = mysql_fetch_array($sql_exec)) { - - $price = $showDetails['price']; - $quantity = $showDetails['order_quantity']; - - $product = $price * $quantity; - $sum[] = $product; - - } - if (isset($sum)) { - echo array_sum($sum); - echo ' '; - echo $personal['currency']; - } - else { - echo '0'; - echo ' '; - echo $personal['currency']; - } - } -} -?> \ No newline at end of file diff --git a/include/menu.php b/include/menu.php index 7d1631a..b0c3d6a 100644 --- a/include/menu.php +++ b/include/menu.php @@ -2,7 +2,7 @@
    • "> My components
    • "> Add component
    • -
    • "> Shopping list
    • +
    • "> Shopping list
    • "> Projects
    • "> My account
    • "> Public components
    • diff --git a/include/routes.php b/include/routes.php index 724e4c9..6e521b6 100644 --- a/include/routes.php +++ b/include/routes.php @@ -25,6 +25,7 @@ $app->get('/terms', 'TermsController:index')->setName('terms'); $app->get('/contact', 'ContactController:index')->setName('contact'); $app->get('/donate', 'DonateController:index')->setName('donate'); +$app->get('/shoplist', 'ShopController:index')->setName('shoplist'); // redirect to php file $app->any('/{filename}.php', function ($request, \Slim\Http\Response $response, $args) { diff --git a/shoplist.php b/shoplist.php deleted file mode 100644 index dd81df4..0000000 --- a/shoplist.php +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - Shopping list - ecDB - - - - -
      - - - - - - - -
      - - - - - - - - - - - - - - - - - - - ShoplistList(); - ?> - -
      - Name - Manufacturer - Package - SMD - Price - Quantity - Quantity to order - - Comment -
      -
      - ShoplistPriceSum(); - ?> -
      -
      - - - - -
      - - diff --git a/views/shop_list.tpl b/views/shop_list.tpl new file mode 100644 index 0000000..52e4695 --- /dev/null +++ b/views/shop_list.tpl @@ -0,0 +1,79 @@ +{extends file='layout.tpl'} + +{block name=title}Shopping list - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + + + + + + + + + + + + + + + + {foreach from=$components item=component} + + + + + + + + + + + + {/foreach} + +
      + Name + + Manufacturer + + Package + + SMD + + Price + + Quantity + + Quantity to order + + Comment +
      + + + {$component.name} + {$component.manufacturer|default:'-'}{$component.package|default:'-'} + {if $component.smd == 'No'} + + {else} + + {/if} + {$component.price|default:'-'}{$component.quantity|default:'-'}{$component.order_quantity|default:'-'} +
      + {if $component.comment == ''} + - + {else} + + + {$component.comment} + + {/if} +
      +
      +
      + {$total_price} {$currency} +
      + +{/block} \ No newline at end of file From 0ad45b82db3c4ac05013c6ffb70c7aab512018e3 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Sat, 10 Jun 2017 15:57:10 +0300 Subject: [PATCH 18/43] Component controller added components list view refactored --- category.php | 115 ------------------ controllers/ComponentController.php | 120 ++++++++++++++++++ include/dependencies.php | 3 + include/include.php | 159 ------------------------ include/include_category_head.php | 93 -------------- include/include_category_sub.php | 56 --------- include/routes.php | 11 +- index_page.php | 182 ---------------------------- views/components.tpl | 135 +++++++++++++++++++++ 9 files changed, 260 insertions(+), 614 deletions(-) delete mode 100644 category.php create mode 100644 controllers/ComponentController.php delete mode 100644 include/include_category_head.php delete mode 100644 include/include_category_sub.php delete mode 100644 index_page.php create mode 100644 views/components.tpl diff --git a/category.php b/category.php deleted file mode 100644 index 5a33aac..0000000 --- a/category.php +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - Category - ecDB - - - - -
      - - - - - - - -
      - -
      -
        - Sub(); - ?> -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - Category(); - ?> - -
      NameCategoryPackagePinsImageDatasheetSMDPriceQuantityComment
      -
      - - - - -
      - - diff --git a/controllers/ComponentController.php b/controllers/ComponentController.php new file mode 100644 index 0000000..05b0a11 --- /dev/null +++ b/controllers/ComponentController.php @@ -0,0 +1,120 @@ +getParam('cat'); + $sub_category_id = $req->getParam('subcat'); + $by = $req->getParam('by'); + $order = $req->getParam('order'); + if (!in_array($order, array('asc', 'desc'))) { + $order = 'asc'; + } + $by_map = array( + 'price' => 'price+0 ' . $order, + 'pins' => 'pins+0 ' . $order, + 'quantity' => 'quantity+0 ' . $order, + 'category' => "nx {$order}, snx {$order}", + 'name' => 'd.name ' . $order, + 'package' => 'package ' . $order, + 'smd' => 'smd ' . $order, + ); + $components_order = in_array($by, $by_map) ? $by_map[$by] : "d.name $order"; + + if (!$category_id && $sub_category_id) { + $sql = "SELECT floor(id / 100) FROM category_sub where id = ?"; + $category_id = $this->db->fetchColumn($sql, array($sub_category_id)); + } + + $sql = "SELECT ch.id + , ch.name + , COUNT(d.id) elements + FROM category_head ch + LEFT JOIN data d ON floor(d.category / 100) = ch.id + GROUP BY ch.name + ORDER BY ch.name ASC"; + $categories = $this->db->fetchAll($sql); + + if ($category_id) { + $sql = "SELECT c.id + , c.name + , COUNT(d.id) elements + FROM category_sub c + LEFT JOIN data d ON d.category = c.id + WHERE floor(c.id / 100) = ? + GROUP BY c.name + ORDER by c.name ASC"; + $sub_categories = $this->db->fetchAll($sql, array($category_id)); + $sub_category_ids = array(); + foreach ($sub_categories as $sub_category) { + $sub_category_ids[] = $sub_category['id']; + } + + $sql = "SELECT category FROM data WHERE owner = ? AND category IN (?) GROUP BY category"; + $stmt = $this->db->executeQuery($sql, array( + $owner, + $sub_category_ids, + ), array( + \PDO::PARAM_INT, + \Doctrine\DBAL\Connection::PARAM_INT_ARRAY, + )); + $subcategories_with_components = $stmt->fetchAll(); + $subcategories_with_components = array_map(function ($row) { + return (int) $row['category']; + }, $subcategories_with_components); + + $this->view->assign('sub_categories', $sub_categories); + $this->view->assign('subcategories_with_components', $subcategories_with_components); + } + + $sql = "SELECT d.id + , d.name + , d.category + , d.package + , d.pins + , d.datasheet + , d.url1 + , d.smd + , d.price + , d.quantity + , d.comment + , d.location + , c.`name` as nx + , sc.name as snx + , sc.id as scid + FROM data d + JOIN category_sub sc ON d.category = sc.id + JOIN category_head c ON c.id = FLOOR(sc.id / 100) + WHERE owner = ?"; + $params = array( + $owner, + ); + if ($category_id) { + $sql .= " AND c.id = ? "; + $params[] = $category_id; + } + if ($sub_category_id) { + $sql .= " AND sc.id = ? "; + $params[] = $sub_category_id; + } + $sql .= "ORDER BY {$components_order}"; + $components = $this->db->fetchAll($sql, $params); + + $this->view->assign('categories', $categories); + $this->view->assign('category_id', $category_id); + $this->view->assign('sub_category_id', $sub_category_id); + $this->view->assign('components', $components); + $this->view->assign('order', $order); + $this->view->assign('selected_menu', 'components'); + + return $this->render('components.tpl'); + } +} + diff --git a/include/dependencies.php b/include/dependencies.php index 082cb59..e2706e8 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -30,6 +30,9 @@ $container['ShopController'] = function ($container) use ($app) { return new \Ecdb\Controllers\ShopController($app); }; +$container['ComponentController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\ComponentController($app); +}; $container['view'] = function ($container) use ($ECDB_VERSION) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); diff --git a/include/include.php b/include/include.php index c024aa0..33f5ee9 100644 --- a/include/include.php +++ b/include/include.php @@ -1,164 +1,5 @@ "; - - echo ''; - - echo ''; - - echo $showDetails['name']; - echo ""; - - echo ""; - - if ($showDetails['category'] < 999) { - $head_cat_id = substr($showDetails['category'], -3, 1); - } - else { - $head_cat_id = substr($showDetails['category'], -4, 2); - } - $subcatid = $showDetails['category']; - - $CategoryName = "SELECT * FROM category_head WHERE id = ".$head_cat_id.""; - $sql_exec_catname = mysql_Query($CategoryName); - - while($showDetailsCat = mysql_fetch_array($sql_exec_catname)) { - $catname = $showDetailsCat['name']; - } - - echo "$catname"; - echo ""; - - echo ""; - $package = $showDetails['package']; - if ($package == ""){ - echo "-"; - } - else{ - echo $package; - } - echo ""; - - echo ""; - $pins = $showDetails['pins']; - if ($pins == ""){ - echo "-"; - } - else{ - echo $pins; - } - echo ""; - - echo ''; - $image = $showDetails['url1']; - if ($image==""){ - echo "-"; - } - - else{ - echo ''; - } - - echo ''; - $datasheet = $showDetails['datasheet']; - if ($datasheet==""){ - echo "-"; - } - - else{ - echo ''; - } - - echo ""; - $smd = $showDetails['smd']; - if ($smd == "No"){ - echo ''; - } - else{ - echo ''; - } - echo ""; - - echo ""; - $price = $showDetails['price']; - if ($price == ""){ - echo "-"; - } - else{ - echo $price; - } - echo ""; - - echo ""; - $quantity = $showDetails['quantity']; - if ($quantity == ""){ - echo "-"; - } - else{ - echo $quantity; - } - echo ""; - - $comment = $showDetails['comment']; - if ($comment==""){ - echo '
      '; - echo "-"; - echo '
      '; - } - else{ - echo '
      '; - echo nl2br($showDetails['comment']); - echo '
      '; - } - echo ""; - } - } public function Category() { require_once('include/login/auth.php'); diff --git a/include/include_category_head.php b/include/include_category_head.php deleted file mode 100644 index 5445037..0000000 --- a/include/include_category_head.php +++ /dev/null @@ -1,93 +0,0 @@ -'; - echo ''; - echo "All"; - echo ' '; - - while ($ShowDetailsCatname = mysql_fetch_array($sql_exec_catname)) { - echo '
    • '; - echo ''; - echo $ShowDetailsCatname['name']; - echo '
    • '; - } - } -} -?> - - diff --git a/include/include_category_sub.php b/include/include_category_sub.php deleted file mode 100644 index cdfce4a..0000000 --- a/include/include_category_sub.php +++ /dev/null @@ -1,56 +0,0 @@ -'; - echo ''; - echo $ShowDetailsSubCatname['name']; - echo ' '; - } - } -} -?> \ No newline at end of file diff --git a/include/routes.php b/include/routes.php index 6e521b6..f2a2dc0 100644 --- a/include/routes.php +++ b/include/routes.php @@ -1,14 +1,7 @@ any('/', function ($request, $response, $args) { - require_once(__DIR__ . '/../index_page.php'); -})->setName('index'); -$app->any('/index.php', function ($request, $response, $args) { - require_once(__DIR__ . '/../index_page.php'); -})->setName('index'); - -// login/logout +$app->get('/', 'ComponentController:listing')->setName('index'); +$app->get('/category', 'ComponentController:listing')->setName('index'); $app->get('/login', 'LoginController:index')->setName('login'); $app->post('/auth', 'LoginController:auth')->setName('auth'); $app->get('/logout', 'LoginController:logout')->setName('logout'); diff --git a/index_page.php b/index_page.php deleted file mode 100644 index f8af78f..0000000 --- a/index_page.php +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - Home - ecDB - - - - -
      - - - - - - - -
      - - - - - - - - - - - - - - - - - - - - Index(); - ?> - -
      - - Name - - Category - - Package - - Pins - - Image - - Datasheet - - SMD - - Price - - Quantity - - Comment -
      -
      - - - - -
      - - diff --git a/views/components.tpl b/views/components.tpl new file mode 100644 index 0000000..662d3ce --- /dev/null +++ b/views/components.tpl @@ -0,0 +1,135 @@ +{extends file='layout.tpl'} + +{block name=title}Home - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + + + + {if $sub_categories} +
      + +
      + {/if} + + + + {assign var="filter_params" value=""} + {if $smarty.get.cat} + {assign var="filter_params" value=$filter_params|cat:'&cat='|cat:$smarty.get.cat} + {/if} + {if $smarty.get.subcat} + {assign var="filter_params" value=$filter_params|cat:'&subcat='|cat:$smarty.get.subcat} + {/if} + + + + + + + + + + + + + + + + + {foreach from=$components item=component} + + + + + + + + + + + + + + {/foreach} + +
      + + Name + + Category + + Package + + Pins + + Image + + Datasheet + + SMD + + Price + + Quantity + + Comment +
      + + {$component.name} + {$component.nx} / {$component.snx} + {$component.package|default:'-'}{$component.pins|default:'-'} + {if $component.url1} + + + + + + + {else} + - + {/if} + + {if $component.datasheet} + + + + {else} + - + {/if} + + {if $component.smd == 'No'} + + {else} + + {/if} + {$component.price|default:'-'}{$component.quantity|default:'-'} + {if $component.comment} +
      + + {$component.comment|@nl2br} +
      + {else} +
      -
      + {/if} +
      + + +{/block} \ No newline at end of file From 3b177432620f36da9cc26a1b0c9fe9f4b88fe732 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 10:14:44 +0300 Subject: [PATCH 19/43] search page refactored --- controllers/ComponentController.php | 57 +++++++++ include/include.php | 185 --------------------------- include/routes.php | 1 + search.php | 186 ---------------------------- views/components_search.tpl | 120 ++++++++++++++++++ views/layout.tpl | 2 +- 6 files changed, 179 insertions(+), 372 deletions(-) delete mode 100644 search.php create mode 100644 views/components_search.tpl diff --git a/controllers/ComponentController.php b/controllers/ComponentController.php index 05b0a11..538cc6b 100644 --- a/controllers/ComponentController.php +++ b/controllers/ComponentController.php @@ -6,6 +6,63 @@ class ComponentController extends BaseController { + public function search(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + $owner = $_SESSION['SESS_MEMBER_ID']; + + $query = $req->getParam('q'); + $query = trim(strip_tags(strtoupper($query))); + $by = $req->getParam('by'); + $order = $req->getParam('order'); + + if (!in_array($order, array('asc', 'desc'))) { + $order = 'asc'; + } + + $by_map = array( + 'price' => 'price+0', + 'pins' => 'pins+0', + 'quantity' => 'quantity+0', + 'name' => 'name', + 'category' => 'category', + 'package' => 'package', + 'smd' => 'smd', + 'manufacturer' => 'manufacturer', + ); + if (!array_key_exists($by, $by_map)) { + $by = 'name'; + } else { + $by = $by_map[$by]; + } + + $sql = "SELECT d.* + , c.`name` as nx + , sc.name as snx + , sc.id as scid + FROM data d + JOIN category_sub sc ON d.category = sc.id + JOIN category_head c ON c.id = FLOOR(sc.id / 100) + WHERE (d.name LIKE ? OR d.package LIKE ? OR d.manufacturer LIKE ? OR d.pins LIKE ? OR d.location LIKE ? OR d.comment LIKE ?) + AND owner = ? + ORDER BY {$by} {$order}"; + $components = $this->db->fetchAll($sql, array( + "%{$query}%", + "%{$query}%", + "%{$query}%", + "%{$query}%", + "%{$query}%", + "%{$query}%", + $owner, + )); + + + + $this->view->assign('components', $components); + $this->view->assign('selected_menu', 'search'); + + return $this->render('components_search.tpl'); + } + public function listing(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { $owner = $_SESSION['SESS_MEMBER_ID']; diff --git a/include/include.php b/include/include.php index 33f5ee9..ad25ed4 100644 --- a/include/include.php +++ b/include/include.php @@ -305,191 +305,6 @@ public function Category() { } } } - public function Search() { - - if(isset($_GET['q'])) { - - require_once('include/login/auth.php'); - include('include/mysql_connect.php'); - - $owner = $_SESSION['SESS_MEMBER_ID']; - - $query = mysql_real_escape_string($_GET['q']); - - $query1 = strtoupper($query); - $query2 = strip_tags($query1); - $find = trim($query2); - - - if ($find == "") { - echo '
      '; - echo "You forgot to enter a search term."; - echo '
      '; - } - else { - - - if (isset($_GET['by'])){ - $by = strip_tags(mysql_real_escape_string($_GET["by"])); - $order_q = strip_tags(mysql_real_escape_string($_GET["order"])); - - if($order_q == 'desc' or $order_q == 'asc'){ - $order = $order_q; - } - else{ - $order = 'asc'; - } - - if($by == 'price' or $by == 'pins' or $by == 'quantity') { - $SearchQuery = "SELECT * FROM data WHERE (name LIKE'%$find%' OR package LIKE'%$find%' OR manufacturer LIKE'%$find%' OR pins LIKE'%$find%' OR location LIKE'%$find%' OR comment LIKE'%$find%') AND owner = $owner ORDER by $by +0 $order"; - } - elseif($by == 'name' or $by == 'category' or $by =='package' or $by =='smd' or $by =='manufacturer') { - $SearchQuery = "SELECT * FROM data WHERE (name LIKE'%$find%' OR package LIKE'%$find%' OR manufacturer LIKE'%$find%' OR pins LIKE'%$find%' OR location LIKE'%$find%' OR comment LIKE'%$find%') AND owner = $owner ORDER by $by $order"; - } - else { - $SearchQuery = "SELECT * FROM data WHERE (name LIKE'%$find%' OR package LIKE'%$find%' OR manufacturer LIKE'%$find%' OR pins LIKE'%$find%' OR location LIKE'%$find%' OR comment LIKE'%$find%') AND owner = $owner ORDER by name ASC"; - } - } - else{ - $SearchQuery = "SELECT * FROM data WHERE (name LIKE'%$find%' OR package LIKE'%$find%' OR manufacturer LIKE'%$find%' OR pins LIKE'%$find%' OR location LIKE'%$find%' OR comment LIKE'%$find%') AND owner = $owner ORDER by name ASC"; - } - - $sql_exec = mysql_query($SearchQuery); - $anymatches = mysql_num_rows($sql_exec); - if ($anymatches == 0) { - echo '
      '; - echo "Sorry, but we can not find an entry to match your query."; - echo '
      '; - } - - while($showDetails = mysql_fetch_array($sql_exec)) { - echo ""; - - echo 'Edit'; - - echo ''; - - echo $showDetails['name']; - echo ""; - - echo ""; - if ($showDetails['category'] < 999) { - $head_cat_id = substr($showDetails['category'], -3, 1); - } - else { - $head_cat_id = substr($showDetails['category'], -4, 2); - } - $subcatid = $showDetails['category']; - - $CategoryName = "SELECT * FROM category_head WHERE id = ".$head_cat_id.""; - $sql_exec_catname = mysql_Query($CategoryName); - - while($showDetailsCat = mysql_fetch_array($sql_exec_catname)) { - $catname = $showDetailsCat['name']; - } - - echo $catname; - echo ""; - - echo ""; - $manufacturer = $showDetails['manufacturer']; - if ($manufacturer == ""){ - echo "-"; - } - else{ - echo $manufacturer; - } - echo ""; - - echo ""; - $package = $showDetails['package']; - if ($package == ""){ - echo "-"; - } - else{ - echo $package; - } - echo ""; - - echo ""; - $pins = $showDetails['pins']; - if ($pins == ""){ - echo "-"; - } - else{ - echo $pins; - } - echo ""; - - echo ''; - $image = $showDetails['url1']; - if ($image==""){ - echo "-"; - } - - else{ - echo ''; - } - - echo ''; - $datasheet = $showDetails['datasheet']; - if ($datasheet==""){ - echo "-"; - } - else{ - echo ''; - } - - echo ""; - $smd = $showDetails['smd']; - if ($smd == "No"){ - echo ''; - } - else{ - echo ''; - } - echo ""; - - echo ""; - $price = $showDetails['price']; - if ($price == ""){ - echo "-"; - } - else{ - echo $price; - } - echo ""; - - echo ""; - echo $showDetails['quantity']; - echo ""; - - $comment = $showDetails['comment']; - if ($comment == ""){ - echo '
      '; - echo "-"; - echo '
      '; - } - else{ - echo '
      '; - echo $showDetails['comment']; - echo '
      '; - } - echo ""; - } - } - } - } public function Add() { require_once('include/login/auth.php'); diff --git a/include/routes.php b/include/routes.php index f2a2dc0..5c6b7e0 100644 --- a/include/routes.php +++ b/include/routes.php @@ -2,6 +2,7 @@ $app->get('/', 'ComponentController:listing')->setName('index'); $app->get('/category', 'ComponentController:listing')->setName('index'); +$app->get('/components/search', 'ComponentController:search')->setName('search'); $app->get('/login', 'LoginController:index')->setName('login'); $app->post('/auth', 'LoginController:auth')->setName('auth'); $app->get('/logout', 'LoginController:logout')->setName('logout'); diff --git a/search.php b/search.php deleted file mode 100644 index 41a6f14..0000000 --- a/search.php +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - Home - ecDB - - - - -
      - - - - - - - -
      -

      Search results

      - - - - - - - - - - - - - - - - - - - - Search(); - ?> - -
      - Name - - Category - - Manufacturer - - Package - - Pins - - Image - - Datasheet - - SMD - - Price - - Quantity - - Comment -
      -
      - - - - -
      - - diff --git a/views/components_search.tpl b/views/components_search.tpl new file mode 100644 index 0000000..dcf0939 --- /dev/null +++ b/views/components_search.tpl @@ -0,0 +1,120 @@ +{extends file='layout.tpl'} + +{block name=title}Home - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + +

      Search results

      + + + {assign var="filter_params" value=""} + {if $smarty.get.cat} + {assign var="filter_params" value=$filter_params|cat:'&cat='|cat:$smarty.get.cat} + {/if} + {if $smarty.get.subcat} + {assign var="filter_params" value=$filter_params|cat:'&subcat='|cat:$smarty.get.subcat} + {/if} + {if $smarty.get.q} + {assign var="filter_params" value=$filter_params|cat:'&q='|cat:$smarty.get.q} + {/if} + + + + + + + + + + + + + + + + + + {foreach from=$components item=component} + + + + + + + + + + + + + + + {/foreach} + +
      + + Name + + Category + + Manufacturer + + Package + + Pins + + Image + + Datasheet + + SMD + + Price + + Quantity + + Comment +
      + + {$component.name} + {$component.nx} / {$component.snx} + {$component.manufacturer|default:'-'}{$component.package|default:'-'}{$component.pins|default:'-'} + {if $component.url1} + + + + + + + {else} + - + {/if} + + {if $component.datasheet} + + + + {else} + - + {/if} + + {if $component.smd == 'No'} + + {else} + + {/if} + {$component.price|default:'-'}{$component.quantity|default:'-'} + {if $component.comment} +
      + + {$component.comment|@nl2br} +
      + {else} +
      -
      + {/if} +
      + + +{/block} \ No newline at end of file diff --git a/views/layout.tpl b/views/layout.tpl index 85162cd..139d1d9 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -28,7 +28,7 @@ Sign out
      -
      From eaf5a979e36cbaa54f52315070ed9f1f5cd1aa60 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 10:30:27 +0300 Subject: [PATCH 20/43] public components refactored --- controllers/ComponentController.php | 7 +++++ include/routes.php | 1 + public.php | 49 ----------------------------- views/components_public.tpl | 19 +++++++++++ views/layout.tpl | 2 +- 5 files changed, 28 insertions(+), 50 deletions(-) delete mode 100644 public.php create mode 100644 views/components_public.tpl diff --git a/controllers/ComponentController.php b/controllers/ComponentController.php index 538cc6b..775fec5 100644 --- a/controllers/ComponentController.php +++ b/controllers/ComponentController.php @@ -63,6 +63,13 @@ public function search(\Slim\Http\Request $req, \Slim\Http\Response $response, $ return $this->render('components_search.tpl'); } + public function public_listing(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + $this->view->assign('selected_menu', 'components_public'); + + return $this->render('components_public.tpl'); + } + public function listing(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { $owner = $_SESSION['SESS_MEMBER_ID']; diff --git a/include/routes.php b/include/routes.php index 5c6b7e0..dab1e7f 100644 --- a/include/routes.php +++ b/include/routes.php @@ -2,6 +2,7 @@ $app->get('/', 'ComponentController:listing')->setName('index'); $app->get('/category', 'ComponentController:listing')->setName('index'); +$app->get('/components/public', 'ComponentController:public_listing')->setName('components_public'); $app->get('/components/search', 'ComponentController:search')->setName('search'); $app->get('/login', 'LoginController:index')->setName('login'); $app->post('/auth', 'LoginController:auth')->setName('auth'); diff --git a/public.php b/public.php deleted file mode 100644 index b9597f5..0000000 --- a/public.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - Home - ecDB - - - - - -
      - - - - - - - - - - -
      -

      Public Components

      - -
      - When you add a component there is a button called "public". If you choose to set that to yes, it means that other people can see that you own that component.

      - - The thought with that setting is, for example; You are building a project and missed to order one component, to skip expensive shipping costs, long shipping time etc. you just make a quick search on ecDB for that component and contact the owner. Hopefully he is kind enough to send you that component quickly for a small charge. -
      - -

      This function is under development...

      -
      - - - - -
      - - diff --git a/views/components_public.tpl b/views/components_public.tpl new file mode 100644 index 0000000..684c8f4 --- /dev/null +++ b/views/components_public.tpl @@ -0,0 +1,19 @@ +{extends file='layout.tpl'} + +{block name=title}Home - ecDB{/block} + +{block name=head}{/block} + +{block name=body} + +

      Public Components

      + +
      + When you add a component there is a button called "public". If you choose to set that to yes, it means that other people can see that you own that component.

      + + The thought with that setting is, for example; You are building a project and missed to order one component, to skip expensive shipping costs, long shipping time etc. you just make a quick search on ecDB for that component and contact the owner. Hopefully he is kind enough to send you that component quickly for a small charge. +
      + +

      This function is under development...

      + +{/block} \ No newline at end of file diff --git a/views/layout.tpl b/views/layout.tpl index 139d1d9..70f1b80 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -43,7 +43,7 @@
    • Shopping list
    • Projects
    • My account
    • -
    • Public components
    • +
    • Public components
    • {/if} {if !$smarty.session.SESS_MEMBER_ID} From 027baba1ec5e50cd0fcd2ef293f32b2dfda45d0b Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 19:07:25 +0300 Subject: [PATCH 21/43] refactored component add/edit/view pages --- add.php | 355 ------------- add_based.php | 378 -------------- component.php | 487 ------------------ controllers/ComponentController.php | 384 ++++++++++++++ edit_component.php | 459 ----------------- .../include_component_add_category_menu.php | 46 -- include/include_component_add_project.php | 34 -- .../include_component_edit_project_add.php | 50 -- .../include_component_edit_project_edit.php | 62 --- .../include_edit_component_project_menu.php | 38 -- include/routes.php | 8 + views/component.tpl | 257 +++++++++ views/component_edit.tpl | 351 +++++++++++++ views/layout.tpl | 2 +- 14 files changed, 1001 insertions(+), 1910 deletions(-) delete mode 100644 add.php delete mode 100644 add_based.php delete mode 100644 component.php delete mode 100644 edit_component.php delete mode 100644 include/include_component_add_category_menu.php delete mode 100644 include/include_component_add_project.php delete mode 100644 include/include_component_edit_project_add.php delete mode 100644 include/include_component_edit_project_edit.php delete mode 100644 include/include_edit_component_project_menu.php create mode 100644 views/component.tpl create mode 100644 views/component_edit.tpl diff --git a/add.php b/add.php deleted file mode 100644 index 6587ce8..0000000 --- a/add.php +++ /dev/null @@ -1,355 +0,0 @@ - - - - - - - - - - - Add component - ecDB - - - - - - - - - - - - -
      - - - - - - - - - - -
      - - - Add(); - ?> - - -
      -
      - -
      - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Name - - - - Category - - - - Quantity - - -
      - Manufacturer - - - - Package - - - - Pins - - -
      - Location - - - - Price - - - - To order - - -
      - SMD - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> - - Scrap - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> - - Public - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> -
      - Weight - - - - Width - - -
      - Depth - - -
      - Datasheet URL - - - - Height - - -
      - Image URL 1 - - - - Image URL 2 - - - - -
      - Image URL 3 - - - - Image URL 4 - - - - -
      - Add component to project - - Quantity -
      - - - -
      -
      -
      - -
      -
      -
      -
      - - - - -
      - - \ No newline at end of file diff --git a/add_based.php b/add_based.php deleted file mode 100644 index 3aa6b89..0000000 --- a/add_based.php +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - - - - - Add component - ecDB - - - - -
      - - - - - - - - - - -
      - -

      Add new component based on

      - - Add(); - ?> - -
      -
      - -
      - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Name - - - - Category - - - - Quantity - - -
      - Manufacturer - - - - Package - - - - Pins - - -
      - Location - - - - Price - - - - To order - - -
      - SMD - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> - - Scrap - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> - - Public - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> -
      - Weight - - - - Width - - -
      - Depth - - -
      - Datasheet URL - - - - Height - - -
      - Image URL 1 - - - - Image URL 2 - - - - -
      - Image URL 3 - - - - Image URL 4 - - - - -
      - Add component to project - - Quantity -
      - - - -
      -
      -
      - -
      -
      -
      -
      - - - - - -
      - - diff --git a/component.php b/component.php deleted file mode 100644 index d2ac59b..0000000 --- a/component.php +++ /dev/null @@ -1,487 +0,0 @@ - - - - - - - - - - - View component - <?php echo $executesql['name']; ?> - ecDB - - - -
      - - - - - - - -
      -

      - '; - echo $executesql_head_catname['name']; - echo ' / '; - - echo ' '; - echo $executesql_sub_catname['name']; - ?> - / -

      - -
      -
      -
      - '; - echo 'No Image'; - echo '
      '; - } - else { - echo ''; - } - ?> -
      -
      -
        - '; - } - ?> - '; - } - ?> - '; - } - ?> -
      -
      -
      - -
      - -
      -
      - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Location - -
      Quantity - -
      - - -
      -
      Price - - Order quantity - -
      - - -
      -
      Manufacturer - - Package - - Pins - -
      SMD - '; - } - else { - echo ''; - } - ?> - Scrap - '; - } - else { - echo ''; - } - ?> - Public - '; - } - else { - echo ''; - } - ?> -
      Width - - Weight - -
      Depth - - -
      Height - - -
      Datasheet - '; - } - ?> -
      -
      - -
      -
      -
      - - - -
      -
      -
      - -
      - - - - -
    - - diff --git a/controllers/ComponentController.php b/controllers/ComponentController.php index 775fec5..9a15607 100644 --- a/controllers/ComponentController.php +++ b/controllers/ComponentController.php @@ -70,6 +70,196 @@ public function public_listing(\Slim\Http\Request $req, \Slim\Http\Response $res return $this->render('components_public.tpl'); } + public function save(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + $owner = $_SESSION['SESS_MEMBER_ID']; + $id = !empty($args['id']) ? $args['id'] : null; + + $new_component = $req->getAttribute('route')->getName() == 'component_add'; + + $component = $req->getParam('component'); + + $name = isset($component['name']) ? $component['name'] : ''; + $quantity = isset($component['quantity']) ? $component['quantity'] : ''; + $category = isset($component['category']) ? $component['category'] : ''; + $comment = isset($component['comment']) ? $component['comment'] : ''; + $order_quantity = isset($component['order_quantity']) ? $component['order_quantity'] : ''; + $price = isset($component['price']) ? $component['price'] : ''; + $location = isset($component['location']) ? $component['location'] : ''; + $manufacturer = isset($component['manufacturer']) ? $component['manufacturer'] : ''; + $package = isset($component['package']) ? $component['package'] : ''; + $pins = isset($component['pins']) ? $component['pins'] : ''; + $scrap = isset($component['scrap']) ? $component['scrap'] : 'No'; + $smd = isset($component['smd']) ? $component['smd'] : 'No'; + $width = isset($component['width']) ? $component['width'] : null; + $height = isset($component['height']) ? $component['height'] : null; + $depth = isset($component['depth']) ? $component['depth'] : null; + $weight = isset($component['weight']) ? $component['weight'] : null; + $datasheet = isset($component['datasheet']) ? $component['datasheet'] : null; + $url1 = isset($component['url1']) ? $component['url1'] : ''; + $url2 = isset($component['url2']) ? $component['url2'] : ''; + $url3 = isset($component['url3']) ? $component['url3'] : ''; + $url4 = isset($component['url4']) ? $component['url4'] : ''; + $public = isset($component['public']) ? $component['public'] : 'No'; + + $project = $req->getParam('project'); + $projquant = $req->getParam('projquant'); + + if (mb_strlen($name) < 2) { + $_SESSION['ERRMSG_ARR'][] = 'You have to specify a name!'; + } + if (!$category) { + $_SESSION['ERRMSG_ARR'][] = 'You have to choose a category!'; + } + if (strlen($comment) >= 2500) { + $_SESSION['ERRMSG_ARR'][] = 'Max 2500 characters in the comment!'; + } + if ($quantity && !is_numeric($quantity)) { + $_SESSION['ERRMSG_ARR'][] = 'The quantity must only be a number!'; + } + if ($pins && !is_numeric($pins)) { + $_SESSION['ERRMSG_ARR'][] = 'The pin-count must only be a number!'; + } + if ($price && !is_numeric($price)) { + $_SESSION['ERRMSG_ARR'][] = 'The price must only be a number!'; + } + if ($order_quantity && !is_numeric($order_quantity)) { + $_SESSION['ERRMSG_ARR'][] = 'The order quantity must only be a number!'; + } + if ($weight && !is_numeric($weight)) { + $_SESSION['ERRMSG_ARR'][] = 'The weight must only be a number!'; + } + if ($width && !is_numeric($width)) { + $_SESSION['ERRMSG_ARR'][] = 'The width must only be a number!'; + } + if ($depth && !is_numeric($depth)) { + $_SESSION['ERRMSG_ARR'][] = 'The depth must only be a number!'; + } + if ($height && !is_numeric($height)) { + $_SESSION['ERRMSG_ARR'][] = 'The height must only be a number!'; + } + if ($projquant && !$project) { + $_SESSION['ERRMSG_ARR'][] = 'You have to choose a project!'; + } + if ($project && !$projquant) { + $_SESSION['ERRMSG_ARR'][] = 'You have to specify a quantity for this component to add to the project!'; + } + + $inserted = false; + $updated = false; + + if (empty($_SESSION['ERRMSG_ARR'])) { + if ($id && !$new_component) { + $updated = $this->db->update('data', array( + 'name' => $name, + 'manufacturer' => $manufacturer, + 'package' => $package, + 'pins' => $pins, + 'smd' => $smd, + 'quantity' => $quantity, + 'location' => $location, + 'scrap' => $scrap, + 'width' => $width, + 'height' => $height, + 'depth' => $depth, + 'weight' => $weight, + 'datasheet' => $datasheet, + 'comment' => $comment, + 'category' => $category, + 'url1' => $url1, + 'url2' => $url2, + 'url3' => $url3, + 'url4' => $url4, + 'price' => $price, + 'order_quantity' => $order_quantity, + 'public' => $public, + ), array( + 'id' => $id, + )); + if ($updated) { + $_SESSION['messages'][] = 'Updated'; + } + + $edit_projects = $req->getParam('projquantedit'); + foreach ($edit_projects as $edit_project_id=>$edit_project_quantity) { + if ($edit_project_quantity < 1) { + $project_deleted = $this->db->delete('projects_data', array( + 'projects_data_owner_id' => $owner, + 'projects_data_project_id' => $edit_project_id, + 'projects_data_component_id' => $id, + )); + if ($project_deleted) { + $_SESSION['messages'][] = 'Component deleted from project'; + } + } else { + $project_updated = $this->db->update('projects_data', array( + 'projects_data_quantity' => $edit_project_quantity, + ), array( + 'projects_data_owner_id' => $owner, + 'projects_data_project_id' => $edit_project_id, + 'projects_data_component_id' => $id, + )); + if ($project_updated) { + $_SESSION['messages'][] = 'Component quantity in project updated'; + } + } + } + } else { + $inserted = $this->db->insert('data', array( + 'owner' => $owner, + 'name' => $name, + 'manufacturer' => $manufacturer, + 'package' => $package, + 'pins' => $pins, + 'smd' => $smd, + 'quantity' => $quantity, + 'location' => $location, + 'scrap' => $scrap, + 'width' => $width, + 'height' => $height, + 'depth' => $depth, + 'weight' => $weight, + 'datasheet' => $datasheet, + 'comment' => $comment, + 'category' => $category, + 'url1' => $url1, + 'url2' => $url2, + 'url3' => $url3, + 'url4' => $url4, + 'price' => $price, + 'order_quantity' => $order_quantity, + 'public' => $public, + )); + if ($inserted) { + $id = $this->db->lastInsertId(); + // TODO: base path here + $_SESSION['messages'][] = "Component added! - View component ({$name})"; + } + } + + if ($project && $projquant) { + $this->db->insert('projects_data', array( + 'projects_data_owner_id' => $owner, + 'projects_data_project_id' => $project, + 'projects_data_component_id' => $id, + 'projects_data_quantity' => $projquant, + )); + } + } + + if ($inserted || $updated) { + return $this->redirect($response, 'component_edit', array( + 'id' => $id, + )); + } + + $args['post_component'] = $component; + + if ($new_component) { + return $this->add($req, $response, $args); + } + return $this->edit($req, $response, $args); + } + public function listing(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { $owner = $_SESSION['SESS_MEMBER_ID']; @@ -180,5 +370,199 @@ public function listing(\Slim\Http\Request $req, \Slim\Http\Response $response, return $this->render('components.tpl'); } + + public function delete(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + $deleted = $this->db->delete('data', array( + 'id' => $args['id'], + 'owner' => $_SESSION['SESS_MEMBER_ID'], + )); + + if ($deleted) { + $_SESSION['messages'][] = 'Component deleted'; + return $this->redirect($response, 'index'); + } + + $_SESSION['ERRMSG_ARR'][] = 'Component not found'; + return $this->redirect($response, 'component', array( + 'id' => $args['id'], + )); + } + + public function edit(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + $owner = $_SESSION['SESS_MEMBER_ID']; + $id = !empty($args['id']) ? $args['id'] : null; + + $component = $this->getComponent($id); + + if (!$component) { + header("Location: error.php?id=2"); + exit; + } + + $category = $this->getCategoriesNames($component['category']); + $project = $this->getComponentProject($component['id']); + + $sql = 'SELECT currency, measurement FROM members WHERE member_id = ?'; + $member_settings = $this->db->fetchAssoc($sql, array( + $owner, + )); + + if (!empty($args['post_component'])) { + $args['post_component']['id'] = $id; + $this->view->assign('component', $args['post_component']); + } else { + $this->view->assign('component', $component); + } + $this->view->assign('member_settings', $member_settings); + $this->view->assign('category', $category); + $this->view->assign('project', $project); + $this->view->assign('projects', $this->getAllProjects()); + $this->view->assign('category_tree', $this->getCategoryTree()); + $this->view->assign('selected_menu', 'components'); + + return $this->render('component_edit.tpl'); + } + + private function getCategoryTree() { + $sql = 'SELECT id, name FROM category_head ORDER by name ASC'; + $data = $this->db->fetchAll($sql); + + $sql = 'SELECT id, name FROM category_sub WHERE floor(id / 100) = ? ORDER by name ASC'; + foreach ($data as &$row) { + $row['subcategories'] = $this->db->fetchAll($sql, array($row['id'])); + } + + return $data; + } + + private function getComponent($id) { + $owner = $_SESSION['SESS_MEMBER_ID']; + + $sql = 'SELECT * FROM data WHERE id = ? AND owner = ?'; + $component = $this->db->fetchAssoc($sql, array( + $id, + $owner, + )); + + return $component; + } + + private function getCategoriesNames($subcategory_id) { + $sql = 'SELECT c.name category_name + , c.id category_id + , cs.name sub_category_name + , cs.id sub_category_id + FROM category_head c + JOIN category_sub cs ON c.id = floor(cs.id / 100) + WHERE cs.id = ?'; + $category = $this->db->fetchAssoc($sql, array( + $subcategory_id, + )); + + return $category; + } + + private function getComponentProject($component_id) { + $sql = "SELECT projects_data.projects_data_project_id + , projects_data.projects_data_quantity + , projects_data.projects_data_project_id + , projects_data.projects_data_component_id + , projects.project_id + , projects.project_name + FROM projects_data + , projects + WHERE projects_data.projects_data_project_id = projects.project_id + AND projects_data.projects_data_component_id = ? + LIMIT 1"; + $project = $this->db->fetchAssoc($sql, array( + $component_id, + )); + return $project; + } + + private function getAllProjects() { + $owner = $_SESSION['SESS_MEMBER_ID']; + + $sql = "SELECT * FROM projects WHERE project_owner = ?"; + $projects = $this->db->fetchAll($sql, array( + $owner, + )); + + return $projects; + } + + public function view(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + $owner = $_SESSION['SESS_MEMBER_ID']; + $id = !empty($args['id']) ? $args['id'] : null; + + $component = $this->getComponent($id); + + if (!$component) { + header("Location: error.php?id=1"); + exit; + } + + $sql = 'SELECT currency, measurement FROM members WHERE member_id = ?'; + $member_settings = $this->db->fetchAssoc($sql, array( + $owner, + )); + + $category = $this->getCategoriesNames($component['category']); + $project = $this->getComponentProject($component['id']); + + $this->view->assign('component', $component); + $this->view->assign('member_settings', $member_settings); + $this->view->assign('category', $category); + $this->view->assign('project', $project); + $this->view->assign('selected_menu', 'components'); + + return $this->render('component.tpl'); + } + + public function add(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + $owner = $_SESSION['SESS_MEMBER_ID']; + $id_based = !empty($args['id']) ? $args['id'] : null; + + $component = false; + if ($id_based) { + $component = $this->getComponent($id_based); + } + + if ($id_based && !$component) { + header("Location: error.php?id=2"); + exit; + } + + if ($component) { + $category = $this->getCategoriesNames($component['category']); + $project = $this->getComponentProject($component['id']); + + $this->view->assign('category', $category); + $this->view->assign('project', $project); + } + + $sql = 'SELECT currency, measurement FROM members WHERE member_id = ?'; + $member_settings = $this->db->fetchAssoc($sql, array( + $owner, + )); + + if (!empty($args['post_component'])) { + if ($id_based) { + $args['post_component']['id'] = $id_based; + } + $this->view->assign('component', $args['post_component']); + } else { + $this->view->assign('component', $component); + } + $this->view->assign('member_settings', $member_settings); + $this->view->assign('projects', $this->getAllProjects()); + $this->view->assign('category_tree', $this->getCategoryTree()); + $this->view->assign('new_component', true); + $this->view->assign('id_based', $id_based); + $this->view->assign('selected_menu', 'component_add'); + + return $this->render('component_edit.tpl'); + } } diff --git a/edit_component.php b/edit_component.php deleted file mode 100644 index 6df4162..0000000 --- a/edit_component.php +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - - - - - Edit component - <?php echo $executesql['name']; ?> - ecDB - - - - -
    - - - - - - - - - - -
    -

    - '; - echo $executesql_head_catname['name']; - echo ' / '; - - echo ' '; - echo $executesql_sub_catname['name']; - ?> - /

    - - - - Add(); - ?> - - -
    -
    - -
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '; - echo ''; - echo ''; - } - else { - echo ''; - echo ''; - echo ''; - } - - ?> - - - - - - -
    - Name - - - - Category - - - - Quantity - - - - -
    - Manufacturer - - - - Package - - - - Pins - - -
    - Location - - - - Price - - - - To order - - - - -
    - SMD - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> - - Scrap - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> - - Public - - Yes '; - echo ' No'; - } - else{ - echo ' Yes '; - echo ' No'; - } - ?> -
    - Weight - - - - Width - - - -
    - Depth - - -
    - Datasheet URL - - - - Height - - -
    - Image URL 1 - - - - Image URL 2 - - - - -
    - Image URL 3 - - - - Image URL 4 - - - - -
    - Add to project - - Quantity - ProjectQuantity
    - - - - - MenuProj(); - ?> -
    - -
    -
    - - - -
    -
    -
    -
    - - - - - -
    - - diff --git a/include/include_component_add_category_menu.php b/include/include_component_add_category_menu.php deleted file mode 100644 index 9ea5c49..0000000 --- a/include/include_component_add_category_menu.php +++ /dev/null @@ -1,46 +0,0 @@ -'; - echo ' - Category - '; - echo ''; - - while ($HeadCategory = mysql_fetch_array($sql_exec_headcat)) { - echo ''; - - $subcatfrom = $HeadCategory['id'] * 100; - $subcatto = $subcatfrom + 99; - - $SubCategoryNameQuery = "SELECT * FROM category_sub WHERE id BETWEEN ".$subcatfrom." AND ".$subcatto." ORDER by name ASC"; - $sql_exec_subcat = mysql_Query($SubCategoryNameQuery); - - while ($SubCategory = mysql_fetch_array($sql_exec_subcat)) { - echo ''; - } - } - } -} -?> \ No newline at end of file diff --git a/include/include_component_add_project.php b/include/include_component_add_project.php deleted file mode 100644 index 730740d..0000000 --- a/include/include_component_add_project.php +++ /dev/null @@ -1,34 +0,0 @@ -'; - echo ' - Project - '; - echo ''; - - while ($Project = mysql_fetch_array($sql_exec_projname)) { - echo ''; - } - } -} -?> \ No newline at end of file diff --git a/include/include_component_edit_project_add.php b/include/include_component_edit_project_add.php deleted file mode 100644 index dd36930..0000000 --- a/include/include_component_edit_project_add.php +++ /dev/null @@ -1,50 +0,0 @@ -'; - echo ' - Project - '; - echo ''; - - $GetDataProject = "SELECT * FROM projects WHERE project_owner = '$owner'"; - $sql = mysql_query($GetDataProject); - - while($row1 = mysql_fetch_array($sql)){ - - $query1 = "SELECT projects_data.projects_data_project_id, projects_data.projects_data_component_id FROM projects_data RIGHT JOIN projects ON projects.project_id = projects_data.projects_data_project_id WHERE projects.project_owner = '$owner'"; - - $result1 = mysql_query($query1); - - echo ''; - } - } -} -?> \ No newline at end of file diff --git a/include/include_component_edit_project_edit.php b/include/include_component_edit_project_edit.php deleted file mode 100644 index 5334a3a..0000000 --- a/include/include_component_edit_project_edit.php +++ /dev/null @@ -1,62 +0,0 @@ -'; - echo ''; - echo ''; - //echo ''; - //echo ''; - echo ''; - echo ''; - } - - $query1 = "SELECT projects_data.projects_data_project_id, projects_data.projects_data_quantity, projects_data.projects_data_project_id, projects_data.projects_data_component_id, projects.project_id, projects.project_name FROM projects_data, projects WHERE projects_data.projects_data_project_id = projects.project_id AND projects_data.projects_data_component_id = '$id' LIMIT 1,18446744073709551615"; - - $result1 = mysql_query($query1) or die(mysql_error()); - - while($row1 = mysql_fetch_array($result1)){ - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo $row1['project_name']; - echo ''; - echo ''; - echo ''; - //echo ''; - //echo ''; - echo ''; - echo ''; - - } - - if (mysql_num_rows($result) == 0) { - echo ''; - echo ''; - echo ''; - echo ''; - } - } -} -?> \ No newline at end of file diff --git a/include/include_edit_component_project_menu.php b/include/include_edit_component_project_menu.php deleted file mode 100644 index 29100ea..0000000 --- a/include/include_edit_component_project_menu.php +++ /dev/null @@ -1,38 +0,0 @@ -'; - echo $Project['project_name']; - echo ''; - } - } -} -?> \ No newline at end of file diff --git a/include/routes.php b/include/routes.php index dab1e7f..52d8db5 100644 --- a/include/routes.php +++ b/include/routes.php @@ -2,6 +2,14 @@ $app->get('/', 'ComponentController:listing')->setName('index'); $app->get('/category', 'ComponentController:listing')->setName('index'); +$app->get('/component/{id:[0-9]+}', 'ComponentController:view')->setName('component'); +$app->get('/component/{id:[0-9]+}/edit', 'ComponentController:edit')->setName('component_edit'); +$app->post('/component/{id:[0-9]+}/edit', 'ComponentController:save')->setName('component_edit'); +$app->post('/component/{id:[0-9]+}/delete', 'ComponentController:delete')->setName('component_delete'); +$app->get('/component/add', 'ComponentController:add')->setName('component_add'); +$app->get('/component/add/{id:[0-9]+}', 'ComponentController:add')->setName('component_add'); +$app->post('/component/add', 'ComponentController:save')->setName('component_add'); +$app->post('/component/add/{id:[0-9]+}', 'ComponentController:save')->setName('component_add'); $app->get('/components/public', 'ComponentController:public_listing')->setName('components_public'); $app->get('/components/search', 'ComponentController:search')->setName('search'); $app->get('/login', 'LoginController:index')->setName('login'); diff --git a/views/component.tpl b/views/component.tpl new file mode 100644 index 0000000..d4c19f5 --- /dev/null +++ b/views/component.tpl @@ -0,0 +1,257 @@ +{extends file='layout.tpl'} + +{block name=title}View component - {$component.name} - ecDB{/block} + +{block name=head} + +{/block} + +{block name=body} +

    + {$category.category_name} / + {$category.sub_category_name} / {$component.name} +

    + +
    +
    +
    + {if $component.url1} + + {else} +
    No Image
    + {/if} +
    +
    + {if $component.url2} +
  • + {/if} + {if $component.url3} +
  • + {/if} + {if $component.url4} +
  • + {/if} +
    +
    +
    + +
    {$component.comment|@nl2br}
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Location{$component.location|default:'-'}
    Quantity + {$component.quantity|default:'-'} + + + Price + {if $component.price} + {$component.price} {$member_settings.currency} + {else} + - + {/if} + Order quantity + {$component.order_quantity|default:'-'} + + +
    Manufacturer + {$component.manufacturer|default:'-'} + Package + {$component.package|default:'-'} + Pins + {$component.pins|default:'-'} +
    SMD + {if $component.smd == "Yes"} + + {else} + + {/if} + Scrap + {if $component.scrap == "Yes"} + + {else} + + {/if} + Public + {if $component.public == "Yes"} + + {else} + + {/if} +
    Width + {if $component.width} + {$component.width} + {if $member_settings.measurement == 1} + mm + {else} + " + {/if} + {else} + - + {/if} + Weight + {if $component.weight} + {$component.weight} + {if $member_settings.measurement == 1} + g + {else} + {*TODO: g?*} + g + {/if} + {else} + - + {/if} +
    Depth + {if $component.depth} + {$component.depth} + {if $member_settings.measurement == 1} + mm + {else} + " + {/if} + {else} + - + {/if} +
    Height + {if $component.height} + {$component.height} + {if $member_settings.measurement == 1} + mm + {else} + " + {/if} + {else} + - + {/if} +
    Datasheet + {if $component.datasheet} + + {else} + - + {/if} +
    +
    + +
    +
    +
    + + + +
    +
    +
    + +
    +
    +{/block} \ No newline at end of file diff --git a/views/component_edit.tpl b/views/component_edit.tpl new file mode 100644 index 0000000..8343a1e --- /dev/null +++ b/views/component_edit.tpl @@ -0,0 +1,351 @@ +{extends file='layout.tpl'} + +{block name=title} + {if !$new_component} + Edit component - {$component.name} - ecDB + {else} + Add component - ecDB + {/if} +{/block} + +{block name=head} + + + + + + + + +{/block} + +{block name=body} + {if !$new_component} +

    + {$category.category_name} / + {$category.sub_category_name} / {$component.name} +

    + {elseif $new_component && $component} +

    Add new component based on {$component.name}

    + {/if} + +
    +
    + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {if $project and !$new_component} + + + + {else} + + + + {/if} + + + + + + {if $project and !$new_component} + + + {else} + + + {/if} + + +
    Name + + Category + + Quantity + + {if !$new_component} + + + {/if} +
    Manufacturer + + Package + + Pins + +
    Location + + Price + {$member_settings.currency} + To order + + {if !$new_component} + + + {/if} +
    SMD + Yes + No + Scrap + Yes + No + Public + Yes + No +
    Weight + + {if $member_settings.measurement == 1} + g + {else} + g {* TODO: g? *} + {/if} + Width + + {if $member_settings.measurement == 1} + mm + {else} + in + {/if} +
    Depth + + {if $member_settings.measurement == 1} + mm + {else} + in + {/if} + + +
    Datasheet URL + + + Height + + + {if $member_settings.measurement == 1} + mm + {else} + in + {/if} +
    Image URL 1 + + Image URL 2 + +
    Image URL 3 + + Image URL 4 + +
    Add to projectQuantityProjectQuantity
    + + + + {$project.project_name} + +
    + +
    +
    + {if !$new_component} + + + + {else} + + {/if} +
    +
    +
    + +
    +
    +{/block} \ No newline at end of file diff --git a/views/layout.tpl b/views/layout.tpl index 70f1b80..cbe7524 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -39,7 +39,7 @@
      {if $smarty.session.SESS_MEMBER_ID}
    • My components
    • -
    • Add component
    • +
    • Add component
    • Shopping list
    • Projects
    • My account
    • From 47e7c98a509831bd56cf56ce809b655216f61bf4 Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 19:09:14 +0300 Subject: [PATCH 22/43] added ajax controller and method for increasing/decreasing quantity/order_quantity counts --- controllers/AjaxController.php | 50 ++++++++++++++++++++++++++++++++++ include/dependencies.php | 3 ++ include/routes.php | 1 + 3 files changed, 54 insertions(+) create mode 100644 controllers/AjaxController.php diff --git a/controllers/AjaxController.php b/controllers/AjaxController.php new file mode 100644 index 0000000..0f5f289 --- /dev/null +++ b/controllers/AjaxController.php @@ -0,0 +1,50 @@ +getParam('component_id'); + $field = $req->getParam('field'); + $increase = (bool) $req->getParam('increase'); + + if (!in_array($field, array('quantity', 'order_quantity'))) { + return $response->withJson(array( + 'error' => 'Unknown component field', + )); + } + + $sql = "UPDATE data SET {$field} = {$field} + 1 WHERE owner = ? AND id = ?"; + if (!$increase) { + $sql = "UPDATE data SET {$field} = {$field} - 1 WHERE owner = ? AND id = ?"; + } + $changes = $this->db->executeUpdate($sql, array( + $owner, + $component_id, + )); + + if (!$changes) { + return $response->withJson(array( + 'error' => 'Component not found', + )); + } + + $sql = 'SELECT * FROM data WHERE owner = ? and id = ?'; + $component = $this->db->fetchAssoc($sql, array( + $owner, + $component_id, + )); + + return $response->withJson(array( + 'data' => array( + 'name' => $field, + 'value' => $component[$field], + ), + )); + } + +} + diff --git a/include/dependencies.php b/include/dependencies.php index e2706e8..c5674fa 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -33,6 +33,9 @@ $container['ComponentController'] = function ($container) use ($app) { return new \Ecdb\Controllers\ComponentController($app); }; +$container['AjaxController'] = function ($container) use ($app) { + return new \Ecdb\Controllers\AjaxController($app); +}; $container['view'] = function ($container) use ($ECDB_VERSION) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); diff --git a/include/routes.php b/include/routes.php index 52d8db5..6a2fced 100644 --- a/include/routes.php +++ b/include/routes.php @@ -12,6 +12,7 @@ $app->post('/component/add/{id:[0-9]+}', 'ComponentController:save')->setName('component_add'); $app->get('/components/public', 'ComponentController:public_listing')->setName('components_public'); $app->get('/components/search', 'ComponentController:search')->setName('search'); +$app->post('/ajax/change_component_count_field', 'AjaxController:component_count')->setName('ajax_component_count'); $app->get('/login', 'LoginController:index')->setName('login'); $app->post('/auth', 'LoginController:auth')->setName('auth'); $app->get('/logout', 'LoginController:logout')->setName('logout'); From 492b35cdc50dcc5399d17eba09a0ca8b8601eb4a Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 21:51:57 +0300 Subject: [PATCH 23/43] refactored autocomplete for name, package, manufacturer --- controllers/AjaxController.php | 19 +++++++++++++++++++ .../autocomplete_manufacturer.php | 12 ------------ include/autocomplete/autocomplete_name.php | 12 ------------ include/autocomplete/autocomplete_package.php | 12 ------------ include/routes.php | 1 + views/component_edit.tpl | 16 ++++------------ views/layout.tpl | 1 + views/project-view.tpl | 1 - 8 files changed, 25 insertions(+), 49 deletions(-) delete mode 100644 include/autocomplete/autocomplete_manufacturer.php delete mode 100644 include/autocomplete/autocomplete_name.php delete mode 100644 include/autocomplete/autocomplete_package.php diff --git a/controllers/AjaxController.php b/controllers/AjaxController.php index 0f5f289..8251f27 100644 --- a/controllers/AjaxController.php +++ b/controllers/AjaxController.php @@ -4,6 +4,25 @@ class AjaxController extends BaseController { + public function autocomplete(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { + + $q = $req->getParam('q'); + $field = $req->getParam('f'); + $q = strtolower($q); + if (!in_array($field, array('manufacturer', 'name', 'package'))) { + $field = 'name'; + } + + $sql = "select DISTINCT {$field} as f from data where {$field} LIKE ? ORDER by {$field} ASC"; + $values = $this->db->fetchAll($sql, array( + "%{$q}%", + )); + + foreach ($values as $value) { + echo $value['f'],"\n"; + } + } + public function component_count(\Slim\Http\Request $req, \Slim\Http\Response $response, $args) { $owner = $_SESSION['SESS_MEMBER_ID']; diff --git a/include/autocomplete/autocomplete_manufacturer.php b/include/autocomplete/autocomplete_manufacturer.php deleted file mode 100644 index 3c673c5..0000000 --- a/include/autocomplete/autocomplete_manufacturer.php +++ /dev/null @@ -1,12 +0,0 @@ - \ No newline at end of file diff --git a/include/autocomplete/autocomplete_name.php b/include/autocomplete/autocomplete_name.php deleted file mode 100644 index f3499b7..0000000 --- a/include/autocomplete/autocomplete_name.php +++ /dev/null @@ -1,12 +0,0 @@ - \ No newline at end of file diff --git a/include/autocomplete/autocomplete_package.php b/include/autocomplete/autocomplete_package.php deleted file mode 100644 index ca7c93b..0000000 --- a/include/autocomplete/autocomplete_package.php +++ /dev/null @@ -1,12 +0,0 @@ - \ No newline at end of file diff --git a/include/routes.php b/include/routes.php index 6a2fced..6ce7006 100644 --- a/include/routes.php +++ b/include/routes.php @@ -13,6 +13,7 @@ $app->get('/components/public', 'ComponentController:public_listing')->setName('components_public'); $app->get('/components/search', 'ComponentController:search')->setName('search'); $app->post('/ajax/change_component_count_field', 'AjaxController:component_count')->setName('ajax_component_count'); +$app->get('/ajax/autocomplete', 'AjaxController:autocomplete')->setName('ajax_autocomplete'); $app->get('/login', 'LoginController:index')->setName('login'); $app->post('/auth', 'LoginController:auth')->setName('auth'); $app->get('/logout', 'LoginController:logout')->setName('logout'); diff --git a/views/component_edit.tpl b/views/component_edit.tpl index 8343a1e..3241e9d 100644 --- a/views/component_edit.tpl +++ b/views/component_edit.tpl @@ -58,28 +58,20 @@ - - {block name=head}{/block} diff --git a/views/project-view.tpl b/views/project-view.tpl index f305eba..122a0ef 100644 --- a/views/project-view.tpl +++ b/views/project-view.tpl @@ -3,7 +3,6 @@ {block name=title}Viewing project - {$project.project_name} - ecDB{/block} {block name=head} - - - - - - - -
      - '; - include 'include/header.php'; - echo ''; - - echo ''; - include 'include/menu.php'; - echo ''; - } - else { - echo ''; - echo ''; - echo ''; - - echo ''; - echo ''; - echo ''; - } - ?> - -
      -

      Contact us

      - If you have a suggestion for ecDB please use this form to let us know about it!

      - - '; - echo 'Please check if you have filled all the fields with valid information.'; - echo '
      '; - } - - if(isset($emailSent) && $emailSent == true) { - echo '
      '; - echo 'Thank you '; - echo $name; - echo '!
      Your message was successfully sent.'; - echo '
      '; - } - ?> - -
      -
      - -
      -
      -
      - -
      -
      -
      - -
      -
      -
      - -
      -
      -
      - -
      - -
      -
      -
      -
      - -
      -
      -
      - -
      - - - - -
    - - diff --git a/include/autocomplete/jquery.js b/include/autocomplete/jquery.js deleted file mode 100644 index cfc36f8..0000000 --- a/include/autocomplete/jquery.js +++ /dev/null @@ -1,3558 +0,0 @@ -(function(){ -/* - * jQuery 1.2.6 - New Wave Javascript - * - * Copyright (c) 2008 John Resig (jquery.com) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * $Date: 2008-05-27 21:17:26 +0200 (Di, 27 Mai 2008) $ - * $Rev: 5700 $ - */ - -// Map over jQuery in case of overwrite -var _jQuery = window.jQuery, -// Map over the $ in case of overwrite - _$ = window.$; - -var jQuery = window.jQuery = window.$ = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context ); -}; - -// A simple way to check for HTML strings or ID strings -// (both of which we optimize for) -var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/, - -// Is it a simple selector - isSimple = /^.[^:#\[\.]*$/, - -// Will speed up references to undefined, and allows munging its name. - undefined; - -jQuery.fn = jQuery.prototype = { - init: function( selector, context ) { - // Make sure that a selection was provided - selector = selector || document; - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this[0] = selector; - this.length = 1; - return this; - } - // Handle HTML strings - if ( typeof selector == "string" ) { - // Are we dealing with HTML string or an ID? - var match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) - selector = jQuery.clean( [ match[1] ], context ); - - // HANDLE: $("#id") - else { - var elem = document.getElementById( match[3] ); - - // Make sure an element was located - if ( elem ){ - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id != match[3] ) - return jQuery().find( selector ); - - // Otherwise, we inject the element directly into the jQuery object - return jQuery( elem ); - } - selector = []; - } - - // HANDLE: $(expr, [context]) - // (which is just equivalent to: $(content).find(expr) - } else - return jQuery( context ).find( selector ); - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) - return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); - - return this.setArray(jQuery.makeArray(selector)); - }, - - // The current version of jQuery being used - jquery: "1.2.6", - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - // The number of elements contained in the matched element set - length: 0, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == undefined ? - - // Return a 'clean' array - jQuery.makeArray( this ) : - - // Return just the object - this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - // Build a new jQuery matched element set - var ret = jQuery( elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Force the current matched set of elements to become - // the specified array of elements (destroying the stack in the process) - // You should use pushStack() in order to do this, but maintain the stack - setArray: function( elems ) { - // Resetting the length to 0, then using the native Array push - // is a super-fast way to populate an object with array-like properties - this.length = 0; - Array.prototype.push.apply( this, elems ); - - return this; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - var ret = -1; - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem && elem.jquery ? elem[0] : elem - , this ); - }, - - attr: function( name, value, type ) { - var options = name; - - // Look for the case where we're accessing a style value - if ( name.constructor == String ) - if ( value === undefined ) - return this[0] && jQuery[ type || "attr" ]( this[0], name ); - - else { - options = {}; - options[ name ] = value; - } - - // Check to see if we're setting style values - return this.each(function(i){ - // Set all the styles - for ( name in options ) - jQuery.attr( - type ? - this.style : - this, - name, jQuery.prop( this, options[ name ], type, i, name ) - ); - }); - }, - - css: function( key, value ) { - // ignore negative width and height values - if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) - value = undefined; - return this.attr( key, value, "curCSS" ); - }, - - text: function( text ) { - if ( typeof text != "object" && text != null ) - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - - var ret = ""; - - jQuery.each( text || this, function(){ - jQuery.each( this.childNodes, function(){ - if ( this.nodeType != 8 ) - ret += this.nodeType != 1 ? - this.nodeValue : - jQuery.fn.text( [ this ] ); - }); - }); - - return ret; - }, - - wrapAll: function( html ) { - if ( this[0] ) - // The elements to wrap the target around - jQuery( html, this[0].ownerDocument ) - .clone() - .insertBefore( this[0] ) - .map(function(){ - var elem = this; - - while ( elem.firstChild ) - elem = elem.firstChild; - - return elem; - }) - .append(this); - - return this; - }, - - wrapInner: function( html ) { - return this.each(function(){ - jQuery( this ).contents().wrapAll( html ); - }); - }, - - wrap: function( html ) { - return this.each(function(){ - jQuery( this ).wrapAll( html ); - }); - }, - - append: function() { - return this.domManip(arguments, true, false, function(elem){ - if (this.nodeType == 1) - this.appendChild( elem ); - }); - }, - - prepend: function() { - return this.domManip(arguments, true, true, function(elem){ - if (this.nodeType == 1) - this.insertBefore( elem, this.firstChild ); - }); - }, - - before: function() { - return this.domManip(arguments, false, false, function(elem){ - this.parentNode.insertBefore( elem, this ); - }); - }, - - after: function() { - return this.domManip(arguments, false, true, function(elem){ - this.parentNode.insertBefore( elem, this.nextSibling ); - }); - }, - - end: function() { - return this.prevObject || jQuery( [] ); - }, - - find: function( selector ) { - var elems = jQuery.map(this, function(elem){ - return jQuery.find( selector, elem ); - }); - - return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? - jQuery.unique( elems ) : - elems ); - }, - - clone: function( events ) { - // Do the clone - var ret = this.map(function(){ - if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { - // IE copies events bound via attachEvent when - // using cloneNode. Calling detachEvent on the - // clone will also remove the events from the orignal - // In order to get around this, we use innerHTML. - // Unfortunately, this means some modifications to - // attributes in IE that are actually only stored - // as properties will not be copied (such as the - // the name attribute on an input). - var clone = this.cloneNode(true), - container = document.createElement("div"); - container.appendChild(clone); - return jQuery.clean([container.innerHTML])[0]; - } else - return this.cloneNode(true); - }); - - // Need to set the expando to null on the cloned set if it exists - // removeData doesn't work here, IE removes it from the original as well - // this is primarily for IE but the data expando shouldn't be copied over in any browser - var clone = ret.find("*").andSelf().each(function(){ - if ( this[ expando ] != undefined ) - this[ expando ] = null; - }); - - // Copy the events from the original to the clone - if ( events === true ) - this.find("*").andSelf().each(function(i){ - if (this.nodeType == 3) - return; - var events = jQuery.data( this, "events" ); - - for ( var type in events ) - for ( var handler in events[ type ] ) - jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); - }); - - // Return the cloned set - return ret; - }, - - filter: function( selector ) { - return this.pushStack( - jQuery.isFunction( selector ) && - jQuery.grep(this, function(elem, i){ - return selector.call( elem, i ); - }) || - - jQuery.multiFilter( selector, this ) ); - }, - - not: function( selector ) { - if ( selector.constructor == String ) - // test special case where just one selector is passed in - if ( isSimple.test( selector ) ) - return this.pushStack( jQuery.multiFilter( selector, this, true ) ); - else - selector = jQuery.multiFilter( selector, this ); - - var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; - return this.filter(function() { - return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; - }); - }, - - add: function( selector ) { - return this.pushStack( jQuery.unique( jQuery.merge( - this.get(), - typeof selector == 'string' ? - jQuery( selector ) : - jQuery.makeArray( selector ) - ))); - }, - - is: function( selector ) { - return !!selector && jQuery.multiFilter( selector, this ).length > 0; - }, - - hasClass: function( selector ) { - return this.is( "." + selector ); - }, - - val: function( value ) { - if ( value == undefined ) { - - if ( this.length ) { - var elem = this[0]; - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type == "select-one"; - - // Nothing was selected - if ( index < 0 ) - return null; - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - if ( option.selected ) { - // Get the specifc value for the option - value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; - - // We don't need an array for one selects - if ( one ) - return value; - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - - // Everything else, we just grab the value - } else - return (this[0].value || "").replace(/\r/g, ""); - - } - - return undefined; - } - - if( value.constructor == Number ) - value += ''; - - return this.each(function(){ - if ( this.nodeType != 1 ) - return; - - if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) - this.checked = (jQuery.inArray(this.value, value) >= 0 || - jQuery.inArray(this.name, value) >= 0); - - else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(value); - - jQuery( "option", this ).each(function(){ - this.selected = (jQuery.inArray( this.value, values ) >= 0 || - jQuery.inArray( this.text, values ) >= 0); - }); - - if ( !values.length ) - this.selectedIndex = -1; - - } else - this.value = value; - }); - }, - - html: function( value ) { - return value == undefined ? - (this[0] ? - this[0].innerHTML : - null) : - this.empty().append( value ); - }, - - replaceWith: function( value ) { - return this.after( value ).remove(); - }, - - eq: function( i ) { - return this.slice( i, i + 1 ); - }, - - slice: function() { - return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function(elem, i){ - return callback.call( elem, i, elem ); - })); - }, - - andSelf: function() { - return this.add( this.prevObject ); - }, - - data: function( key, value ){ - var parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - if ( data === undefined && this.length ) - data = jQuery.data( this[0], key ); - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - } else - return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ - jQuery.data( this, key, value ); - }); - }, - - removeData: function( key ){ - return this.each(function(){ - jQuery.removeData( this, key ); - }); - }, - - domManip: function( args, table, reverse, callback ) { - var clone = this.length > 1, elems; - - return this.each(function(){ - if ( !elems ) { - elems = jQuery.clean( args, this.ownerDocument ); - - if ( reverse ) - elems.reverse(); - } - - var obj = this; - - if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) - obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); - - var scripts = jQuery( [] ); - - jQuery.each(elems, function(){ - var elem = clone ? - jQuery( this ).clone( true )[0] : - this; - - // execute all scripts after the elements have been injected - if ( jQuery.nodeName( elem, "script" ) ) - scripts = scripts.add( elem ); - else { - // Remove any inner scripts for later evaluation - if ( elem.nodeType == 1 ) - scripts = scripts.add( jQuery( "script", elem ).remove() ); - - // Inject the elements into the document - callback.call( obj, elem ); - } - }); - - scripts.each( evalScript ); - }); - } -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -function evalScript( i, elem ) { - if ( elem.src ) - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - - else - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - - if ( elem.parentNode ) - elem.parentNode.removeChild( elem ); -} - -function now(){ - return +new Date; -} - -jQuery.extend = jQuery.fn.extend = function() { - // copy reference to target object - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; - - // Handle a deep copy situation - if ( target.constructor == Boolean ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target != "object" && typeof target != "function" ) - target = {}; - - // extend jQuery itself if only one argument is passed - if ( length == i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) - // Extend the base object - for ( var name in options ) { - var src = target[ name ], copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) - continue; - - // Recurse if we're merging object values - if ( deep && copy && typeof copy == "object" && !copy.nodeType ) - target[ name ] = jQuery.extend( deep, - // Never move original objects, clone them - src || ( copy.length != null ? [ ] : { } ) - , copy ); - - // Don't bring in undefined values - else if ( copy !== undefined ) - target[ name ] = copy; - - } - - // Return the modified object - return target; -}; - -var expando = "jQuery" + now(), uuid = 0, windowData = {}, - // exclude the following css properties to add px - exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, - // cache defaultView - defaultView = document.defaultView || {}; - -jQuery.extend({ - noConflict: function( deep ) { - window.$ = _$; - - if ( deep ) - window.jQuery = _jQuery; - - return jQuery; - }, - - // See test/unit/core.js for details concerning this function. - isFunction: function( fn ) { - return !!fn && typeof fn != "string" && !fn.nodeName && - fn.constructor != Array && /^[\s[]?function/.test( fn + "" ); - }, - - // check if an element is in a (or is an) XML document - isXMLDoc: function( elem ) { - return elem.documentElement && !elem.body || - elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; - }, - - // Evalulates a script in a global context - globalEval: function( data ) { - data = jQuery.trim( data ); - - if ( data ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - if ( jQuery.browser.msie ) - script.text = data; - else - script.appendChild( document.createTextNode( data ) ); - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); - }, - - cache: {}, - - data: function( elem, name, data ) { - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ]; - - // Compute a unique ID for the element - if ( !id ) - id = elem[ expando ] = ++uuid; - - // Only generate the data cache if we're - // trying to access or manipulate it - if ( name && !jQuery.cache[ id ] ) - jQuery.cache[ id ] = {}; - - // Prevent overriding the named cache with undefined values - if ( data !== undefined ) - jQuery.cache[ id ][ name ] = data; - - // Return the named cache data, or the ID for the element - return name ? - jQuery.cache[ id ][ name ] : - id; - }, - - removeData: function( elem, name ) { - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ]; - - // If we want to remove a specific section of the element's data - if ( name ) { - if ( jQuery.cache[ id ] ) { - // Remove the section of cache data - delete jQuery.cache[ id ][ name ]; - - // If we've removed all the data, remove the element's cache - name = ""; - - for ( name in jQuery.cache[ id ] ) - break; - - if ( !name ) - jQuery.removeData( elem ); - } - - // Otherwise, we want to remove all of the element's data - } else { - // Clean up the element expando - try { - delete elem[ expando ]; - } catch(e){ - // IE has trouble directly removing the expando - // but it's ok with using removeAttribute - if ( elem.removeAttribute ) - elem.removeAttribute( expando ); - } - - // Completely remove the data cache - delete jQuery.cache[ id ]; - } - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, length = object.length; - - if ( args ) { - if ( length == undefined ) { - for ( name in object ) - if ( callback.apply( object[ name ], args ) === false ) - break; - } else - for ( ; i < length; ) - if ( callback.apply( object[ i++ ], args ) === false ) - break; - - // A special, fast, case for the most common use of each - } else { - if ( length == undefined ) { - for ( name in object ) - if ( callback.call( object[ name ], name, object[ name ] ) === false ) - break; - } else - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} - } - - return object; - }, - - prop: function( elem, value, type, i, name ) { - // Handle executable functions - if ( jQuery.isFunction( value ) ) - value = value.call( elem, i ); - - // Handle passing in a number to a CSS property - return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? - value + "px" : - value; - }, - - className: { - // internal only, use addClass("class") - add: function( elem, classNames ) { - jQuery.each((classNames || "").split(/\s+/), function(i, className){ - if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) - elem.className += (elem.className ? " " : "") + className; - }); - }, - - // internal only, use removeClass("class") - remove: function( elem, classNames ) { - if (elem.nodeType == 1) - elem.className = classNames != undefined ? - jQuery.grep(elem.className.split(/\s+/), function(className){ - return !jQuery.className.has( classNames, className ); - }).join(" ") : - ""; - }, - - // internal only, use hasClass("class") - has: function( elem, className ) { - return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; - } - }, - - // A method for quickly swapping in/out CSS properties to get correct calculations - swap: function( elem, options, callback ) { - var old = {}; - // Remember the old values, and insert the new ones - for ( var name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - callback.call( elem ); - - // Revert the old values - for ( var name in options ) - elem.style[ name ] = old[ name ]; - }, - - css: function( elem, name, force ) { - if ( name == "width" || name == "height" ) { - var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; - - function getWH() { - val = name == "width" ? elem.offsetWidth : elem.offsetHeight; - var padding = 0, border = 0; - jQuery.each( which, function() { - padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; - border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; - }); - val -= Math.round(padding + border); - } - - if ( jQuery(elem).is(":visible") ) - getWH(); - else - jQuery.swap( elem, props, getWH ); - - return Math.max(0, val); - } - - return jQuery.curCSS( elem, name, force ); - }, - - curCSS: function( elem, name, force ) { - var ret, style = elem.style; - - // A helper method for determining if an element's values are broken - function color( elem ) { - if ( !jQuery.browser.safari ) - return false; - - // defaultView is cached - var ret = defaultView.getComputedStyle( elem, null ); - return !ret || ret.getPropertyValue("color") == ""; - } - - // We need to handle opacity special in IE - if ( name == "opacity" && jQuery.browser.msie ) { - ret = jQuery.attr( style, "opacity" ); - - return ret == "" ? - "1" : - ret; - } - // Opera sometimes will give the wrong display answer, this fixes it, see #2037 - if ( jQuery.browser.opera && name == "display" ) { - var save = style.outline; - style.outline = "0 solid black"; - style.outline = save; - } - - // Make sure we're using the right name for getting the float value - if ( name.match( /float/i ) ) - name = styleFloat; - - if ( !force && style && style[ name ] ) - ret = style[ name ]; - - else if ( defaultView.getComputedStyle ) { - - // Only "float" is needed here - if ( name.match( /float/i ) ) - name = "float"; - - name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); - - var computedStyle = defaultView.getComputedStyle( elem, null ); - - if ( computedStyle && !color( elem ) ) - ret = computedStyle.getPropertyValue( name ); - - // If the element isn't reporting its values properly in Safari - // then some display: none elements are involved - else { - var swap = [], stack = [], a = elem, i = 0; - - // Locate all of the parent display: none elements - for ( ; a && color(a); a = a.parentNode ) - stack.unshift(a); - - // Go through and make them visible, but in reverse - // (It would be better if we knew the exact display type that they had) - for ( ; i < stack.length; i++ ) - if ( color( stack[ i ] ) ) { - swap[ i ] = stack[ i ].style.display; - stack[ i ].style.display = "block"; - } - - // Since we flip the display style, we have to handle that - // one special, otherwise get the value - ret = name == "display" && swap[ stack.length - 1 ] != null ? - "none" : - ( computedStyle && computedStyle.getPropertyValue( name ) ) || ""; - - // Finally, revert the display styles back - for ( i = 0; i < swap.length; i++ ) - if ( swap[ i ] != null ) - stack[ i ].style.display = swap[ i ]; - } - - // We should always get a number back from opacity - if ( name == "opacity" && ret == "" ) - ret = "1"; - - } else if ( elem.currentStyle ) { - var camelCase = name.replace(/\-(\w)/g, function(all, letter){ - return letter.toUpperCase(); - }); - - ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { - // Remember the original values - var left = style.left, rsLeft = elem.runtimeStyle.left; - - // Put in the new values to get a computed value out - elem.runtimeStyle.left = elem.currentStyle.left; - style.left = ret || 0; - ret = style.pixelLeft + "px"; - - // Revert the changed values - style.left = left; - elem.runtimeStyle.left = rsLeft; - } - } - - return ret; - }, - - clean: function( elems, context ) { - var ret = []; - context = context || document; - // !context.createElement fails in IE with an error but returns typeof 'object' - if (typeof context.createElement == 'undefined') - context = context.ownerDocument || context[0] && context[0].ownerDocument || document; - - jQuery.each(elems, function(i, elem){ - if ( !elem ) - return; - - if ( elem.constructor == Number ) - elem += ''; - - // Convert html string into DOM nodes - if ( typeof elem == "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ - return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? - all : - front + ">"; - }); - - // Trim whitespace, otherwise indexOf won't work as expected - var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); - - var wrap = - // option or optgroup - !tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && - [ 1, "", "
    " ] || - - !tags.indexOf("", "" ] || - - // matched above - (!tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - // IE can't serialize and \ No newline at end of file diff --git a/include/middlewares.php b/include/middlewares.php index 7727a9e..14bd37b 100644 --- a/include/middlewares.php +++ b/include/middlewares.php @@ -78,3 +78,10 @@ return $next($request, $response); }); + +$app->add(function ($request, $response, $next) use ($config) { + + $this->view->assign('ga', $config['google_analytics']); + + return $next($request, $response); +}); diff --git a/views/layout.tpl b/views/layout.tpl index 6111027..c4a7c91 100644 --- a/views/layout.tpl +++ b/views/layout.tpl @@ -8,6 +8,23 @@ {block name=title}Home - ecDB{/block} + {if $ga.account} + + {/if} {block name=head}{/block} From 353d270117d6074be80ce9c9ba599980367d63df Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 22:13:15 +0300 Subject: [PATCH 26/43] configuration for smarty compiled templates --- config/config.php | 5 +++++ include/dependencies.php | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/config/config.php b/config/config.php index d02bacd..6a7b1f0 100644 --- a/config/config.php +++ b/config/config.php @@ -18,3 +18,8 @@ 'account' => '', // UA-xxxxxxxx-x 'site' => '', // ecdb.net ); + +/** + * Directory where Smarty will store compiled templates + */ +$config['smarty_compile_dir'] = sys_get_temp_dir(); diff --git a/include/dependencies.php b/include/dependencies.php index c5674fa..cadbc80 100644 --- a/include/dependencies.php +++ b/include/dependencies.php @@ -36,9 +36,10 @@ $container['AjaxController'] = function ($container) use ($app) { return new \Ecdb\Controllers\AjaxController($app); }; -$container['view'] = function ($container) use ($ECDB_VERSION) { +$container['view'] = function ($container) use ($ECDB_VERSION, $config) { $smarty = new Smarty(); $smarty->setTemplateDir(__DIR__ . '/../views'); + $smarty->setCompileDir($config['smarty_compile_dir']); $smarty->assign('ECDB_VERSION', $ECDB_VERSION); $smarty->error_reporting = E_ALL & ~E_NOTICE; From 127e144fba8044937e9fb7b4e3ae54761efc205b Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 23:02:46 +0300 Subject: [PATCH 27/43] refactor error pages --- controllers/BaseController.php | 6 ++++ controllers/ComponentController.php | 9 ++--- error.php | 56 ----------------------------- include/footer.php | 21 ----------- include/header.php | 30 ---------------- include/login/auth.php | 15 -------- include/login/loginmodule.css | 34 ------------------ include/menu.php | 11 ------ include/mysql_connect.php | 10 ------ views/error.tpl | 19 ++++++++++ 10 files changed, 28 insertions(+), 183 deletions(-) delete mode 100644 error.php delete mode 100644 include/footer.php delete mode 100644 include/header.php delete mode 100644 include/login/auth.php delete mode 100644 include/login/loginmodule.css delete mode 100644 include/menu.php delete mode 100644 include/mysql_connect.php create mode 100644 views/error.tpl diff --git a/controllers/BaseController.php b/controllers/BaseController.php index b3fdbad..03c6775 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -45,6 +45,12 @@ protected function render($template_filename) { return $this->view->display($template_filename); } + protected function renderError(\Slim\Http\Response $response, $error_code) { + $this->view->assign('error_code', $error_code); + $this->view->display('error.tpl'); + return $response->withStatus(403); + } + protected function redirect($response, $path_or_name, $args=array()) { try { $path = $this->app->getContainer()->get('router')->pathFor($path_or_name, $args); diff --git a/controllers/ComponentController.php b/controllers/ComponentController.php index 9a15607..2d1c9d9 100644 --- a/controllers/ComponentController.php +++ b/controllers/ComponentController.php @@ -396,8 +396,7 @@ public function edit(\Slim\Http\Request $req, \Slim\Http\Response $response, $ar $component = $this->getComponent($id); if (!$component) { - header("Location: error.php?id=2"); - exit; + return $this->renderError($response, 2); } $category = $this->getCategoriesNames($component['category']); @@ -499,8 +498,7 @@ public function view(\Slim\Http\Request $req, \Slim\Http\Response $response, $ar $component = $this->getComponent($id); if (!$component) { - header("Location: error.php?id=1"); - exit; + return $this->renderError($response, 1); } $sql = 'SELECT currency, measurement FROM members WHERE member_id = ?'; @@ -530,8 +528,7 @@ public function add(\Slim\Http\Request $req, \Slim\Http\Response $response, $arg } if ($id_based && !$component) { - header("Location: error.php?id=2"); - exit; + return $this->renderError($response, 2); } if ($component) { diff --git a/error.php b/error.php deleted file mode 100644 index 8ea087f..0000000 --- a/error.php +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - Error - ecDB - - - - -
    - - - - - - - -
    -
    - -
    -
    - - - - -
    - - diff --git a/include/footer.php b/include/footer.php deleted file mode 100644 index 8ad3a1c..0000000 --- a/include/footer.php +++ /dev/null @@ -1,21 +0,0 @@ -
    -
    -
    © 2010 - ecDB - Created by Nils Fredriksson - Contact us - Terms & Privacy
    -
    - - - - members, - - - components and - - - projects. - -
    -
    -
    - Design by -
    -
    \ No newline at end of file diff --git a/include/header.php b/include/header.php deleted file mode 100644 index 019ddd4..0000000 --- a/include/header.php +++ /dev/null @@ -1,30 +0,0 @@ - - diff --git a/include/login/auth.php b/include/login/auth.php deleted file mode 100644 index 69461d1..0000000 --- a/include/login/auth.php +++ /dev/null @@ -1,15 +0,0 @@ - \ No newline at end of file diff --git a/include/login/loginmodule.css b/include/login/loginmodule.css deleted file mode 100644 index e6e6d39..0000000 --- a/include/login/loginmodule.css +++ /dev/null @@ -1,34 +0,0 @@ -body { - font: 11px Verdana, Arial, Helvetica, sans-serif; - color: #666666; - margin: 0px; - padding: 20px 10px 0px; -} -.textfield { - font-size: 11px; - color: #333333; - background: #F7F7F7; - border: 1px solid #CCCCCC; - padding-left: 1px; -} -h1 { - color: #99CC00; - margin: 0px 0px 5px; - padding: 0px 0px 3px; - font: bold 18px Verdana, Arial, Helvetica, sans-serif; - border-bottom: 1px dashed #E6E8ED; -} -a { - color: #2D3954; - font-size: 11px; -} -a:hover { - color: #99CC00; -} -.err { - color: #FF9900; -} -th { - font-weight: bold; - text-align: left; -} diff --git a/include/menu.php b/include/menu.php deleted file mode 100644 index b0c3d6a..0000000 --- a/include/menu.php +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/include/mysql_connect.php b/include/mysql_connect.php deleted file mode 100644 index 5565c8a..0000000 --- a/include/mysql_connect.php +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/views/error.tpl b/views/error.tpl new file mode 100644 index 0000000..b605be8 --- /dev/null +++ b/views/error.tpl @@ -0,0 +1,19 @@ +{extends file='layout.tpl'} + +{block name=title}Error - ecDB{/block} + +{block name=head}{/block} + +{block name=body} +
    + {if $error_code == 1} + You don't have permission to view this component. + {elseif $error_code == 2} + You don't have permission to edit this component. + {elseif $error_code == 3} + Oh crap! Something broke... + {else} + Error! + {/if} +
    +{/block} \ No newline at end of file From 742cc1762897a230e34698d8268ed99b14793e5c Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 23:03:58 +0300 Subject: [PATCH 28/43] add php version requirement --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 1c48489..bea1c47 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "require": { "doctrine/dbal": "*", "erusev/parsedown": "*", + "php": "^5.5.0 || ^7.0", "slim/slim": "^3.8", "smarty/smarty": "^3.1" } From e14ccd635572505033ac28187ecada600978138e Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 23:07:59 +0300 Subject: [PATCH 29/43] remove unused error pages --- error/400.html | 61 -------------------------------------------------- error/401.html | 61 -------------------------------------------------- error/403.html | 61 -------------------------------------------------- error/404.html | 61 -------------------------------------------------- error/405.html | 61 -------------------------------------------------- error/500.html | 61 -------------------------------------------------- error/502.html | 61 -------------------------------------------------- error/503.html | 61 -------------------------------------------------- 8 files changed, 488 deletions(-) delete mode 100644 error/400.html delete mode 100644 error/401.html delete mode 100644 error/403.html delete mode 100644 error/404.html delete mode 100644 error/405.html delete mode 100644 error/500.html delete mode 100644 error/502.html delete mode 100644 error/503.html diff --git a/error/400.html b/error/400.html deleted file mode 100644 index f83ae58..0000000 --- a/error/400.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 400 - Bad Request! - - - - - -
    - -
    -

    The following error occurred:

    -

    You have used invalid syntax.

    -

    Please contact the webmaster with any queries.

    -
    - -
    - - diff --git a/error/401.html b/error/401.html deleted file mode 100644 index 49c7b47..0000000 --- a/error/401.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 401 - Unauthorized! - - - - - -
    - -
    -

    The following error occurred:

    -

    The URL requested requires authorisation.

    -

    Please contact the webmaster with any queries.

    -
    - -
    - - diff --git a/error/403.html b/error/403.html deleted file mode 100644 index 12934ce..0000000 --- a/error/403.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 403 - Forbidden! - - - - - -
    - -
    -

    The following error occurred:

    -

    You are not permitted to access the requested URL.

    -

    Please contact the webmaster with any queries.

    -
    - -
    - - diff --git a/error/404.html b/error/404.html deleted file mode 100644 index fb17b2a..0000000 --- a/error/404.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 404 - Not Found! - - - - - -
    - -
    -

    The following error occurred:

    -

    The requested URL was not found on this server.

    -

    Please check the URL or contact the webmaster.

    -
    - -
    - - diff --git a/error/405.html b/error/405.html deleted file mode 100644 index e5f66a8..0000000 --- a/error/405.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 405 - Method Not Allowed! - - - - - -
    - -
    -

    The following error occurred:

    -

    The method used is not permitted.

    -

    Please contact the webmaster with any queries.

    -
    - -
    - - diff --git a/error/500.html b/error/500.html deleted file mode 100644 index 4413bf5..0000000 --- a/error/500.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 500 - Internal Server Error! - - - - - -
    - -
    -

    The following error occurred:

    -

    The requested URL caused an internal server error.

    -

    If you get this message repeatedly please contact the webmaster.

    -
    - -
    - - diff --git a/error/502.html b/error/502.html deleted file mode 100644 index 4bcdc95..0000000 --- a/error/502.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 502 - Bad Gateway! - - - - - -
    - -
    -

    The following error occurred:

    -

    This server received an invalid response from an upstream server it accessed to fulfill the request.

    -

    If you get this message repeatedly please contact the webmaster.

    -
    - -
    - - diff --git a/error/503.html b/error/503.html deleted file mode 100644 index 983ce26..0000000 --- a/error/503.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - ERROR 503 - Service Unavailable! - - - - - -
    - -
    -

    The following error occurred:

    -

    The Service is not available at the moment due to a temporary overloading or maintenance of the server. Please try again later.

    -

    Please contact the webmaster with any queries.

    -
    - -
    - - From a170e74308b22cecccc76fbdfc48008cba4d2f5b Mon Sep 17 00:00:00 2001 From: Peeter Normak Date: Mon, 19 Jun 2017 23:22:08 +0300 Subject: [PATCH 30/43] move index page, all js and css files under htdocs --- .htaccess => htdocs/.htaccess | 18 +- .../css}/jquery.autocomplete.css | 98 +- {include => htdocs/css}/jquery.tweet.css | 0 {include => htdocs/css}/style.css | 2 +- {img => htdocs/img}/about/add.png | Bin {img => htdocs/img}/about/add_thumbnail.png | Bin {img => htdocs/img}/about/index.png | Bin {img => htdocs/img}/about/index_thumbnail.png | Bin {img => htdocs/img}/about/shoplist.png | Bin .../img}/about/shoplist_thumbnail.png | Bin {img => htdocs/img}/apple.png | Bin {img => htdocs/img}/bg.png | Bin {img => htdocs/img}/boxSize.png | Bin {img => htdocs/img}/checkbox_checked.png | Bin {img => htdocs/img}/checkbox_unchecked.png | Bin {img => htdocs/img}/checkmark.png | Bin {img => htdocs/img}/cube.png | Bin {img => htdocs/img}/cur_dollar.png | Bin {img => htdocs/img}/dataBackground.png | Bin {img => htdocs/img}/dataBackground.psd | Bin {img => htdocs/img}/doc_lines_stright.png | Bin {img => htdocs/img}/document.png | Bin {img => htdocs/img}/ecdbSpriteV1.png | Bin {img => htdocs/img}/ecdbSpriteV1.psd | Bin {img => htdocs/img}/ecdb_loggo.png | Bin {img => htdocs/img}/ecdb_loggo.psd | Bin {img => htdocs/img}/icon-search.png | Bin {img => htdocs/img}/inbox.png | Bin .../autocomplete => htdocs/img}/indicator.gif | Bin {img => htdocs/img}/key.png | Bin {img => htdocs/img}/pencil.png | Bin {img => htdocs/img}/picture.png | Bin {img => htdocs/img}/print.png | Bin {img => htdocs/img}/round_minus.png | Bin {img => htdocs/img}/round_plus.png | Bin {img => htdocs/img}/save.png | Bin {img => htdocs/img}/share.png | Bin {img => htdocs/img}/shop_cart.png | Bin {img => htdocs/img}/spechbubble.png | Bin {img => htdocs/img}/spechbubble_sq.png | Bin {img => htdocs/img}/trash.png | Bin {img => htdocs/img}/user.png | Bin htdocs/index.php | 15 + .../js}/jquery.autocomplete.js | 1614 ++++++++--------- {include => htdocs/js}/jquery.tweet.js | 0 index.php | 15 - views/component_edit.tpl | 10 +- views/layout.tpl | 2 +- 48 files changed, 887 insertions(+), 887 deletions(-) rename .htaccess => htdocs/.htaccess (96%) rename {include/autocomplete => htdocs/css}/jquery.autocomplete.css (86%) rename {include => htdocs/css}/jquery.tweet.css (100%) rename {include => htdocs/css}/style.css (99%) rename {img => htdocs/img}/about/add.png (100%) rename {img => htdocs/img}/about/add_thumbnail.png (100%) rename {img => htdocs/img}/about/index.png (100%) rename {img => htdocs/img}/about/index_thumbnail.png (100%) rename {img => htdocs/img}/about/shoplist.png (100%) rename {img => htdocs/img}/about/shoplist_thumbnail.png (100%) rename {img => htdocs/img}/apple.png (100%) rename {img => htdocs/img}/bg.png (100%) rename {img => htdocs/img}/boxSize.png (100%) rename {img => htdocs/img}/checkbox_checked.png (100%) rename {img => htdocs/img}/checkbox_unchecked.png (100%) rename {img => htdocs/img}/checkmark.png (100%) rename {img => htdocs/img}/cube.png (100%) rename {img => htdocs/img}/cur_dollar.png (100%) rename {img => htdocs/img}/dataBackground.png (100%) rename {img => htdocs/img}/dataBackground.psd (100%) rename {img => htdocs/img}/doc_lines_stright.png (100%) rename {img => htdocs/img}/document.png (100%) rename {img => htdocs/img}/ecdbSpriteV1.png (100%) rename {img => htdocs/img}/ecdbSpriteV1.psd (100%) rename {img => htdocs/img}/ecdb_loggo.png (100%) rename {img => htdocs/img}/ecdb_loggo.psd (100%) rename {img => htdocs/img}/icon-search.png (100%) rename {img => htdocs/img}/inbox.png (100%) rename {include/autocomplete => htdocs/img}/indicator.gif (100%) rename {img => htdocs/img}/key.png (100%) rename {img => htdocs/img}/pencil.png (100%) rename {img => htdocs/img}/picture.png (100%) rename {img => htdocs/img}/print.png (100%) rename {img => htdocs/img}/round_minus.png (100%) rename {img => htdocs/img}/round_plus.png (100%) rename {img => htdocs/img}/save.png (100%) rename {img => htdocs/img}/share.png (100%) rename {img => htdocs/img}/shop_cart.png (100%) rename {img => htdocs/img}/spechbubble.png (100%) rename {img => htdocs/img}/spechbubble_sq.png (100%) rename {img => htdocs/img}/trash.png (100%) rename {img => htdocs/img}/user.png (100%) create mode 100644 htdocs/index.php rename {include/autocomplete => htdocs/js}/jquery.autocomplete.js (96%) rename {include => htdocs/js}/jquery.tweet.js (100%) delete mode 100644 index.php diff --git a/.htaccess b/htdocs/.htaccess similarity index 96% rename from .htaccess rename to htdocs/.htaccess index bab5b6a..b2aafe3 100644 --- a/.htaccess +++ b/htdocs/.htaccess @@ -1,9 +1,9 @@ -## Default .htaccess file -## RewriteEngine On -## RewriteCond %{HTTP_HOST} !^www\.ecdb\.net -## RewriteRule (.*) http://www.ecdb.net/$1 [R=301,L] - -RewriteEngine on -RewriteCond %{REQUEST_URI} !^/?index.php$ -RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png)$ -RewriteRule . index.php +## Default .htaccess file +## RewriteEngine On +## RewriteCond %{HTTP_HOST} !^www\.ecdb\.net +## RewriteRule (.*) http://www.ecdb.net/$1 [R=301,L] + +RewriteEngine on +RewriteCond %{REQUEST_URI} !^/?index.php$ +RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png)$ +RewriteRule . index.php diff --git a/include/autocomplete/jquery.autocomplete.css b/htdocs/css/jquery.autocomplete.css similarity index 86% rename from include/autocomplete/jquery.autocomplete.css rename to htdocs/css/jquery.autocomplete.css index cc8b179..4739367 100644 --- a/include/autocomplete/jquery.autocomplete.css +++ b/htdocs/css/jquery.autocomplete.css @@ -1,49 +1,49 @@ -.ac_results { - padding: 0px; - border: 1px solid #888; - background-color: white; - box-shadow:0 0 5px #aaa; - overflow: hidden; - z-index: 99999; - min-width:210px; -} - -.ac_results ul { - width: 100%; - list-style-position: outside; - list-style: none; - padding: 0; - margin: 0; -} - -.ac_results li { - margin: 0px; - padding:5px; - cursor: default; - display: block; - /* - if width will be 100% horizontal scrollbar will apear - when scroll mode will be used - */ - /*width: 100%;*/ - font-size: 14px; - /* - it is very important, if line-height not setted or setted - in relative units scroll will be broken in firefox - */ - line-height: 16px; - overflow: hidden; -} - -.ac_loading { - background: white url('indicator.gif') right center no-repeat; -} - -.ac_odd { - background-color: #eee; -} - -.ac_over { - background-color: #404040; - color:#fff; -} +.ac_results { + padding: 0px; + border: 1px solid #888; + background-color: white; + box-shadow:0 0 5px #aaa; + overflow: hidden; + z-index: 99999; + min-width:210px; +} + +.ac_results ul { + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; +} + +.ac_results li { + margin: 0px; + padding:5px; + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font-size: 14px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; +} + +.ac_loading { + background: white url('../img/indicator.gif') right center no-repeat; +} + +.ac_odd { + background-color: #eee; +} + +.ac_over { + background-color: #404040; + color:#fff; +} diff --git a/include/jquery.tweet.css b/htdocs/css/jquery.tweet.css similarity index 100% rename from include/jquery.tweet.css rename to htdocs/css/jquery.tweet.css diff --git a/include/style.css b/htdocs/css/style.css similarity index 99% rename from include/style.css rename to htdocs/css/style.css index 2c70b8e..597f567 100644 --- a/include/style.css +++ b/htdocs/css/style.css @@ -215,7 +215,7 @@ div.aboutComponentHeader{overflow:auto;} color:#888; font-size:14px; text-shadow:0 1px 0 #fff; - background:url("/img/dataBackground.png") #f7f7f7; + background:url("../img/dataBackground.png") #f7f7f7; border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px; } div.componentGallery div.smallImages{float:left;text-align:right;} diff --git a/img/about/add.png b/htdocs/img/about/add.png similarity index 100% rename from img/about/add.png rename to htdocs/img/about/add.png diff --git a/img/about/add_thumbnail.png b/htdocs/img/about/add_thumbnail.png similarity index 100% rename from img/about/add_thumbnail.png rename to htdocs/img/about/add_thumbnail.png diff --git a/img/about/index.png b/htdocs/img/about/index.png similarity index 100% rename from img/about/index.png rename to htdocs/img/about/index.png diff --git a/img/about/index_thumbnail.png b/htdocs/img/about/index_thumbnail.png similarity index 100% rename from img/about/index_thumbnail.png rename to htdocs/img/about/index_thumbnail.png diff --git a/img/about/shoplist.png b/htdocs/img/about/shoplist.png similarity index 100% rename from img/about/shoplist.png rename to htdocs/img/about/shoplist.png diff --git a/img/about/shoplist_thumbnail.png b/htdocs/img/about/shoplist_thumbnail.png similarity index 100% rename from img/about/shoplist_thumbnail.png rename to htdocs/img/about/shoplist_thumbnail.png diff --git a/img/apple.png b/htdocs/img/apple.png similarity index 100% rename from img/apple.png rename to htdocs/img/apple.png diff --git a/img/bg.png b/htdocs/img/bg.png similarity index 100% rename from img/bg.png rename to htdocs/img/bg.png diff --git a/img/boxSize.png b/htdocs/img/boxSize.png similarity index 100% rename from img/boxSize.png rename to htdocs/img/boxSize.png diff --git a/img/checkbox_checked.png b/htdocs/img/checkbox_checked.png similarity index 100% rename from img/checkbox_checked.png rename to htdocs/img/checkbox_checked.png diff --git a/img/checkbox_unchecked.png b/htdocs/img/checkbox_unchecked.png similarity index 100% rename from img/checkbox_unchecked.png rename to htdocs/img/checkbox_unchecked.png diff --git a/img/checkmark.png b/htdocs/img/checkmark.png similarity index 100% rename from img/checkmark.png rename to htdocs/img/checkmark.png diff --git a/img/cube.png b/htdocs/img/cube.png similarity index 100% rename from img/cube.png rename to htdocs/img/cube.png diff --git a/img/cur_dollar.png b/htdocs/img/cur_dollar.png similarity index 100% rename from img/cur_dollar.png rename to htdocs/img/cur_dollar.png diff --git a/img/dataBackground.png b/htdocs/img/dataBackground.png similarity index 100% rename from img/dataBackground.png rename to htdocs/img/dataBackground.png diff --git a/img/dataBackground.psd b/htdocs/img/dataBackground.psd similarity index 100% rename from img/dataBackground.psd rename to htdocs/img/dataBackground.psd diff --git a/img/doc_lines_stright.png b/htdocs/img/doc_lines_stright.png similarity index 100% rename from img/doc_lines_stright.png rename to htdocs/img/doc_lines_stright.png diff --git a/img/document.png b/htdocs/img/document.png similarity index 100% rename from img/document.png rename to htdocs/img/document.png diff --git a/img/ecdbSpriteV1.png b/htdocs/img/ecdbSpriteV1.png similarity index 100% rename from img/ecdbSpriteV1.png rename to htdocs/img/ecdbSpriteV1.png diff --git a/img/ecdbSpriteV1.psd b/htdocs/img/ecdbSpriteV1.psd similarity index 100% rename from img/ecdbSpriteV1.psd rename to htdocs/img/ecdbSpriteV1.psd diff --git a/img/ecdb_loggo.png b/htdocs/img/ecdb_loggo.png similarity index 100% rename from img/ecdb_loggo.png rename to htdocs/img/ecdb_loggo.png diff --git a/img/ecdb_loggo.psd b/htdocs/img/ecdb_loggo.psd similarity index 100% rename from img/ecdb_loggo.psd rename to htdocs/img/ecdb_loggo.psd diff --git a/img/icon-search.png b/htdocs/img/icon-search.png similarity index 100% rename from img/icon-search.png rename to htdocs/img/icon-search.png diff --git a/img/inbox.png b/htdocs/img/inbox.png similarity index 100% rename from img/inbox.png rename to htdocs/img/inbox.png diff --git a/include/autocomplete/indicator.gif b/htdocs/img/indicator.gif similarity index 100% rename from include/autocomplete/indicator.gif rename to htdocs/img/indicator.gif diff --git a/img/key.png b/htdocs/img/key.png similarity index 100% rename from img/key.png rename to htdocs/img/key.png diff --git a/img/pencil.png b/htdocs/img/pencil.png similarity index 100% rename from img/pencil.png rename to htdocs/img/pencil.png diff --git a/img/picture.png b/htdocs/img/picture.png similarity index 100% rename from img/picture.png rename to htdocs/img/picture.png diff --git a/img/print.png b/htdocs/img/print.png similarity index 100% rename from img/print.png rename to htdocs/img/print.png diff --git a/img/round_minus.png b/htdocs/img/round_minus.png similarity index 100% rename from img/round_minus.png rename to htdocs/img/round_minus.png diff --git a/img/round_plus.png b/htdocs/img/round_plus.png similarity index 100% rename from img/round_plus.png rename to htdocs/img/round_plus.png diff --git a/img/save.png b/htdocs/img/save.png similarity index 100% rename from img/save.png rename to htdocs/img/save.png diff --git a/img/share.png b/htdocs/img/share.png similarity index 100% rename from img/share.png rename to htdocs/img/share.png diff --git a/img/shop_cart.png b/htdocs/img/shop_cart.png similarity index 100% rename from img/shop_cart.png rename to htdocs/img/shop_cart.png diff --git a/img/spechbubble.png b/htdocs/img/spechbubble.png similarity index 100% rename from img/spechbubble.png rename to htdocs/img/spechbubble.png diff --git a/img/spechbubble_sq.png b/htdocs/img/spechbubble_sq.png similarity index 100% rename from img/spechbubble_sq.png rename to htdocs/img/spechbubble_sq.png diff --git a/img/trash.png b/htdocs/img/trash.png similarity index 100% rename from img/trash.png rename to htdocs/img/trash.png diff --git a/img/user.png b/htdocs/img/user.png similarity index 100% rename from img/user.png rename to htdocs/img/user.png diff --git a/htdocs/index.php b/htdocs/index.php new file mode 100644 index 0000000..4066da1 --- /dev/null +++ b/htdocs/index.php @@ -0,0 +1,15 @@ + array( + 'determineRouteBeforeAppMiddleware' => true, + ), +)); + +require_once __DIR__ . '/../include/dependencies.php'; +require_once __DIR__ . '/../include/middlewares.php'; +require_once __DIR__ . '/../include/routes.php'; + +$app->run(); diff --git a/include/autocomplete/jquery.autocomplete.js b/htdocs/js/jquery.autocomplete.js similarity index 96% rename from include/autocomplete/jquery.autocomplete.js rename to htdocs/js/jquery.autocomplete.js index 37a6a8a..9d12a29 100644 --- a/include/autocomplete/jquery.autocomplete.js +++ b/htdocs/js/jquery.autocomplete.js @@ -1,808 +1,808 @@ -/* - * jQuery Autocomplete plugin 1.1 - * - * Copyright (c) 2009 Jörn Zaefferer - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $ - */ - -;(function($) { - -$.fn.extend({ - autocomplete: function(urlOrData, options) { - var isUrl = typeof urlOrData == "string"; - options = $.extend({}, $.Autocompleter.defaults, { - url: isUrl ? urlOrData : null, - data: isUrl ? null : urlOrData, - delay: isUrl ? $.Autocompleter.defaults.delay : 10, - max: options && !options.scroll ? 10 : 150 - }, options); - - // if highlight is set to false, replace it with a do-nothing function - options.highlight = options.highlight || function(value) { return value; }; - - // if the formatMatch option is not specified, then use formatItem for backwards compatibility - options.formatMatch = options.formatMatch || options.formatItem; - - return this.each(function() { - new $.Autocompleter(this, options); - }); - }, - result: function(handler) { - return this.bind("result", handler); - }, - search: function(handler) { - return this.trigger("search", [handler]); - }, - flushCache: function() { - return this.trigger("flushCache"); - }, - setOptions: function(options){ - return this.trigger("setOptions", [options]); - }, - unautocomplete: function() { - return this.trigger("unautocomplete"); - } -}); - -$.Autocompleter = function(input, options) { - - var KEY = { - UP: 38, - DOWN: 40, - DEL: 46, - TAB: 9, - RETURN: 13, - ESC: 27, - COMMA: 188, - PAGEUP: 33, - PAGEDOWN: 34, - BACKSPACE: 8 - }; - - // Create $ object for input element - var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass); - - var timeout; - var previousValue = ""; - var cache = $.Autocompleter.Cache(options); - var hasFocus = 0; - var lastKeyPressCode; - var config = { - mouseDownOnSelect: false - }; - var select = $.Autocompleter.Select(options, input, selectCurrent, config); - - var blockSubmit; - - // prevent form submit in opera when selecting with return key - $.browser.opera && $(input.form).bind("submit.autocomplete", function() { - if (blockSubmit) { - blockSubmit = false; - return false; - } - }); - - // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all - $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) { - // a keypress means the input has focus - // avoids issue where input had focus before the autocomplete was applied - hasFocus = 1; - // track last key pressed - lastKeyPressCode = event.keyCode; - switch(event.keyCode) { - - case KEY.UP: - event.preventDefault(); - if ( select.visible() ) { - select.prev(); - } else { - onChange(0, true); - } - break; - - case KEY.DOWN: - event.preventDefault(); - if ( select.visible() ) { - select.next(); - } else { - onChange(0, true); - } - break; - - case KEY.PAGEUP: - event.preventDefault(); - if ( select.visible() ) { - select.pageUp(); - } else { - onChange(0, true); - } - break; - - case KEY.PAGEDOWN: - event.preventDefault(); - if ( select.visible() ) { - select.pageDown(); - } else { - onChange(0, true); - } - break; - - // matches also semicolon - case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA: - case KEY.TAB: - case KEY.RETURN: - if( selectCurrent() ) { - // stop default to prevent a form submit, Opera needs special handling - event.preventDefault(); - blockSubmit = true; - return false; - } - break; - - case KEY.ESC: - select.hide(); - break; - - default: - clearTimeout(timeout); - timeout = setTimeout(onChange, options.delay); - break; - } - }).focus(function(){ - // track whether the field has focus, we shouldn't process any - // results if the field no longer has focus - hasFocus++; - }).blur(function() { - hasFocus = 0; - if (!config.mouseDownOnSelect) { - hideResults(); - } - }).click(function() { - // show select when clicking in a focused field - if ( hasFocus++ > 1 && !select.visible() ) { - onChange(0, true); - } - }).bind("search", function() { - // TODO why not just specifying both arguments? - var fn = (arguments.length > 1) ? arguments[1] : null; - function findValueCallback(q, data) { - var result; - if( data && data.length ) { - for (var i=0; i < data.length; i++) { - if( data[i].result.toLowerCase() == q.toLowerCase() ) { - result = data[i]; - break; - } - } - } - if( typeof fn == "function" ) fn(result); - else $input.trigger("result", result && [result.data, result.value]); - } - $.each(trimWords($input.val()), function(i, value) { - request(value, findValueCallback, findValueCallback); - }); - }).bind("flushCache", function() { - cache.flush(); - }).bind("setOptions", function() { - $.extend(options, arguments[1]); - // if we've updated the data, repopulate - if ( "data" in arguments[1] ) - cache.populate(); - }).bind("unautocomplete", function() { - select.unbind(); - $input.unbind(); - $(input.form).unbind(".autocomplete"); - }); - - - function selectCurrent() { - var selected = select.selected(); - if( !selected ) - return false; - - var v = selected.result; - previousValue = v; - - if ( options.multiple ) { - var words = trimWords($input.val()); - if ( words.length > 1 ) { - var seperator = options.multipleSeparator.length; - var cursorAt = $(input).selection().start; - var wordAt, progress = 0; - $.each(words, function(i, word) { - progress += word.length; - if (cursorAt <= progress) { - wordAt = i; - return false; - } - progress += seperator; - }); - words[wordAt] = v; - // TODO this should set the cursor to the right position, but it gets overriden somewhere - //$.Autocompleter.Selection(input, progress + seperator, progress + seperator); - v = words.join( options.multipleSeparator ); - } - v += options.multipleSeparator; - } - - $input.val(v); - hideResultsNow(); - $input.trigger("result", [selected.data, selected.value]); - return true; - } - - function onChange(crap, skipPrevCheck) { - if( lastKeyPressCode == KEY.DEL ) { - select.hide(); - return; - } - - var currentValue = $input.val(); - - if ( !skipPrevCheck && currentValue == previousValue ) - return; - - previousValue = currentValue; - - currentValue = lastWord(currentValue); - if ( currentValue.length >= options.minChars) { - $input.addClass(options.loadingClass); - if (!options.matchCase) - currentValue = currentValue.toLowerCase(); - request(currentValue, receiveData, hideResultsNow); - } else { - stopLoading(); - select.hide(); - } - }; - - function trimWords(value) { - if (!value) - return [""]; - if (!options.multiple) - return [$.trim(value)]; - return $.map(value.split(options.multipleSeparator), function(word) { - return $.trim(value).length ? $.trim(word) : null; - }); - } - - function lastWord(value) { - if ( !options.multiple ) - return value; - var words = trimWords(value); - if (words.length == 1) - return words[0]; - var cursorAt = $(input).selection().start; - if (cursorAt == value.length) { - words = trimWords(value) - } else { - words = trimWords(value.replace(value.substring(cursorAt), "")); - } - return words[words.length - 1]; - } - - // fills in the input box w/the first match (assumed to be the best match) - // q: the term entered - // sValue: the first matching result - function autoFill(q, sValue){ - // autofill in the complete box w/the first match as long as the user hasn't entered in more data - // if the last user key pressed was backspace, don't autofill - if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) { - // fill in the value (keep the case the user has typed) - $input.val($input.val() + sValue.substring(lastWord(previousValue).length)); - // select the portion of the value not typed by the user (so the next character will erase) - $(input).selection(previousValue.length, previousValue.length + sValue.length); - } - }; - - function hideResults() { - clearTimeout(timeout); - timeout = setTimeout(hideResultsNow, 200); - }; - - function hideResultsNow() { - var wasVisible = select.visible(); - select.hide(); - clearTimeout(timeout); - stopLoading(); - if (options.mustMatch) { - // call search and run callback - $input.search( - function (result){ - // if no value found, clear the input box - if( !result ) { - if (options.multiple) { - var words = trimWords($input.val()).slice(0, -1); - $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") ); - } - else { - $input.val( "" ); - $input.trigger("result", null); - } - } - } - ); - } - }; - - function receiveData(q, data) { - if ( data && data.length && hasFocus ) { - stopLoading(); - select.display(data, q); - autoFill(q, data[0].value); - select.show(); - } else { - hideResultsNow(); - } - }; - - function request(term, success, failure) { - if (!options.matchCase) - term = term.toLowerCase(); - var data = cache.load(term); - // recieve the cached data - if (data && data.length) { - success(term, data); - // if an AJAX url has been supplied, try loading the data now - } else if( (typeof options.url == "string") && (options.url.length > 0) ){ - - var extraParams = { - timestamp: +new Date() - }; - $.each(options.extraParams, function(key, param) { - extraParams[key] = typeof param == "function" ? param() : param; - }); - - $.ajax({ - // try to leverage ajaxQueue plugin to abort previous requests - mode: "abort", - // limit abortion to this input - port: "autocomplete" + input.name, - dataType: options.dataType, - url: options.url, - data: $.extend({ - q: lastWord(term), - limit: options.max - }, extraParams), - success: function(data) { - var parsed = options.parse && options.parse(data) || parse(data); - cache.add(term, parsed); - success(term, parsed); - } - }); - } else { - // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match - select.emptyList(); - failure(term); - } - }; - - function parse(data) { - var parsed = []; - var rows = data.split("\n"); - for (var i=0; i < rows.length; i++) { - var row = $.trim(rows[i]); - if (row) { - row = row.split("|"); - parsed[parsed.length] = { - data: row, - value: row[0], - result: options.formatResult && options.formatResult(row, row[0]) || row[0] - }; - } - } - return parsed; - }; - - function stopLoading() { - $input.removeClass(options.loadingClass); - }; - -}; - -$.Autocompleter.defaults = { - inputClass: "ac_input", - resultsClass: "ac_results", - loadingClass: "ac_loading", - minChars: 1, - delay: 400, - matchCase: false, - matchSubset: true, - matchContains: false, - cacheLength: 10, - max: 100, - mustMatch: false, - extraParams: {}, - selectFirst: true, - formatItem: function(row) { return row[0]; }, - formatMatch: null, - autoFill: false, - width: 0, - multiple: false, - multipleSeparator: ", ", - highlight: function(value, term) { - return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1"); - }, - scroll: true, - scrollHeight: 180 -}; - -$.Autocompleter.Cache = function(options) { - - var data = {}; - var length = 0; - - function matchSubset(s, sub) { - if (!options.matchCase) - s = s.toLowerCase(); - var i = s.indexOf(sub); - if (options.matchContains == "word"){ - i = s.toLowerCase().search("\\b" + sub.toLowerCase()); - } - if (i == -1) return false; - return i == 0 || options.matchContains; - }; - - function add(q, value) { - if (length > options.cacheLength){ - flush(); - } - if (!data[q]){ - length++; - } - data[q] = value; - } - - function populate(){ - if( !options.data ) return false; - // track the matches - var stMatchSets = {}, - nullData = 0; - - // no url was specified, we need to adjust the cache length to make sure it fits the local data store - if( !options.url ) options.cacheLength = 1; - - // track all options for minChars = 0 - stMatchSets[""] = []; - - // loop through the array and create a lookup structure - for ( var i = 0, ol = options.data.length; i < ol; i++ ) { - var rawValue = options.data[i]; - // if rawValue is a string, make an array otherwise just reference the array - rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue; - - var value = options.formatMatch(rawValue, i+1, options.data.length); - if ( value === false ) - continue; - - var firstChar = value.charAt(0).toLowerCase(); - // if no lookup array for this character exists, look it up now - if( !stMatchSets[firstChar] ) - stMatchSets[firstChar] = []; - - // if the match is a string - var row = { - value: value, - data: rawValue, - result: options.formatResult && options.formatResult(rawValue) || value - }; - - // push the current match into the set list - stMatchSets[firstChar].push(row); - - // keep track of minChars zero items - if ( nullData++ < options.max ) { - stMatchSets[""].push(row); - } - }; - - // add the data items to the cache - $.each(stMatchSets, function(i, value) { - // increase the cache size - options.cacheLength++; - // add to the cache - add(i, value); - }); - } - - // populate any existing data - setTimeout(populate, 25); - - function flush(){ - data = {}; - length = 0; - } - - return { - flush: flush, - add: add, - populate: populate, - load: function(q) { - if (!options.cacheLength || !length) - return null; - /* - * if dealing w/local data and matchContains than we must make sure - * to loop through all the data collections looking for matches - */ - if( !options.url && options.matchContains ){ - // track all matches - var csub = []; - // loop through all the data grids for matches - for( var k in data ){ - // don't search through the stMatchSets[""] (minChars: 0) cache - // this prevents duplicates - if( k.length > 0 ){ - var c = data[k]; - $.each(c, function(i, x) { - // if we've got a match, add it to the array - if (matchSubset(x.value, q)) { - csub.push(x); - } - }); - } - } - return csub; - } else - // if the exact item exists, use it - if (data[q]){ - return data[q]; - } else - if (options.matchSubset) { - for (var i = q.length - 1; i >= options.minChars; i--) { - var c = data[q.substr(0, i)]; - if (c) { - var csub = []; - $.each(c, function(i, x) { - if (matchSubset(x.value, q)) { - csub[csub.length] = x; - } - }); - return csub; - } - } - } - return null; - } - }; -}; - -$.Autocompleter.Select = function (options, input, select, config) { - var CLASSES = { - ACTIVE: "ac_over" - }; - - var listItems, - active = -1, - data, - term = "", - needsInit = true, - element, - list; - - // Create results - function init() { - if (!needsInit) - return; - element = $("
    ") - .hide() - .addClass(options.resultsClass) - .css("position", "absolute") - .appendTo(document.body); - - list = $("