- <?php 
- /* 
-  * Copyright (C) 2017 Karmabunny Pty Ltd. 
-  * 
-  * This file is a part of SproutCMS. 
-  * 
-  * SproutCMS is free software: you can redistribute it and/or modify it under the terms 
-  * of the GNU General Public License as published by the Free Software Foundation, either 
-  * version 2 of the License, or (at your option) any later version. 
-  * 
-  * For more information, visit <http://getsproutcms.com>. 
-  */ 
-   
- namespace Sprout\Controllers\Admin; 
-   
- use Exception; 
-   
- use Sprout\Helpers\AdminAuth; 
- use Sprout\Helpers\AdminError; 
- use Sprout\Helpers\AdminPerms; 
- use Sprout\Helpers\Email; 
- use Sprout\Helpers\EmailText; 
- use Sprout\Helpers\Notification; 
- use Sprout\Helpers\Pdb; 
- use Sprout\Helpers\Security; 
- use Sprout\Helpers\Url; 
- use Sprout\Helpers\Validator; 
-   
-   
- /** 
- * Handles most processing for operators 
- **/ 
- class OperatorAdminController extends HasCategoriesAdminController 
- { 
-     /** 
-      * The maximum permissable password length; this is likely limited by the hash method used 
-      * Currently set to bcrypt's truncate length of 72 
-      */ 
-     const MAX_PASSWORD_LENGTH = 72; 
-   
-     protected $controller_name = 'operator'; 
-     protected $friendly_name = 'Operators'; 
-     protected $add_defaults = array( 
-         'active' => 1, 
-     ); 
-     protected $action_log = true; 
-   
-   
-     /** 
-     * The categories which can be edited by the logged in user 
-     **/ 
-     private $manage_cats; 
-   
-   
-     public function __construct() 
-     { 
-         $this->main_columns = [ 
-             'Name' => 'name', 
-             'Username' => 'username', 
-             'Email' => 'email', 
-         ]; 
-   
-         $this->manage_cats = AdminPerms::getManageOperatorCategories(); 
-   
-         if (!AdminPerms::canAccess('access_operators')) { 
-             $this->main_where[] = "(SELECT 1 FROM ~operators_cat_join WHERE operator_id = item.id AND cat_id IN ({$cats}) LIMIT 1) = 1"; 
-         } 
-   
-         parent::__construct(); 
-     } 
-   
-   
-     /** 
-     * Show tools - but only for full access ops 
-     **/ 
-     public function _getTools() 
-     { 
-         if (!-  AdminPerms ::canAccess('access_operators')) return array();
 
-   
-         $tools = parent::_getTools(); 
-   
-         $tools[] = '<li class="config"><a href="' . EmailText::adminEditUrl('operator.welcome') . '">Edit welcome message email</a></li>'; 
-   
-         return $tools; 
-     } 
-   
-   
-     /** 
-     * Get contents list - but only for partial access ops 
-     **/ 
-     public function _getContents() 
-     { 
-         if (count($this->manage_cats) == 0) { 
-             return new AdminError('Access denied'); 
-         } 
-   
-         return parent::_getContents(); 
-     } 
-   
-   
-     /** 
-     * Get add form - but only for partial access ops 
-     **/ 
-     public function _getAddForm() 
-     { 
-         if (count($this->manage_cats) == 0) { 
-             return new AdminError('Access denied'); 
-         } 
-   
-         return parent::_getAddForm(); 
-     } 
-   
-   
-     /** 
-      * Return the sub-actions for adding; for spec {@see AdminController::renderSubActions} 
-      * @return array 
-      */ 
-     public function _getAddSubActions() 
-     { 
-         $actions = parent::_getAddSubActions(); 
-         // Add your actions here, like this: $actions[] = [ ... ]; 
-         return $actions; 
-     } 
-   
-   
-     /** 
-     * Get edit form - but only for partial access ops or for editing your own record 
-     **/ 
-     public function _getEditForm($item_id) 
-     { 
-         if (!AdminPerms::canEditOperator($item_id) and $item_id != AdminAuth::getId()) { 
-             return new AdminError('Access denied'); 
-         } 
-   
-         return parent::_getEditForm($item_id); 
-     } 
-   
-   
-     /** 
-     * Get delete form - but only for partial access ops 
-     **/ 
-     public function _getDeleteForm($item_id) 
-     { 
-         if (!AdminPerms::canEditOperator($item_id)) { 
-             return new AdminError('Access denied'); 
-         } 
-   
-         if ($item_id == AdminAuth::getLocalId()) { 
-             return new AdminError('You cannot delete your own record'); 
-         } 
-   
-         return parent::_getDeleteForm($item_id); 
-     } 
-   
-   
-   
-     /** 
-     * Pre-render hook for adding 
-     **/ 
-     protected function _addPreRender($view) 
-     { 
-         parent::_addPreRender($view); 
-   
-         $view->cats = $this->manage_cats; 
-     } 
-   
-   
-     /** 
-     * Saves the provided POST data into a new record in the database 
-     * 
-     * @param int $item_id After saving, the new record id will be returned in this parameter 
-     * @param bool True on success, false on failure 
-     **/ 
-     public function _addSave(&$item_id) 
-     { 
-         if (count($this->manage_cats) == 0) return false; 
-   
-         $_SESSION['admin']['field_values'] =-  Validator ::trim($_POST);
 
-         $result = true; 
-   
-         $valid = new Validator($_POST); 
-         $valid->required(['name', 'email', 'username', 'password1', 'password2']); 
-         $valid->check('name', 'Validity::length', 0, 200); 
-         $valid->check('email', 'Validity::email'); 
-         $valid->check('email', 'Validity::length', 0, 200); 
-         $valid->check('username', 'Validity::length', 0, 50); 
-         $valid->check('username', 'Validity::uniqueValue', 'operators', 'username', 0, 'An operator already exists with that username'); 
-         $valid->check('username', 'Validity::regex', '/^[a-zA-Z0-9]+$/'); 
-         $valid->check('password1', 'Validity::length', 8, self::MAX_PASSWORD_LENGTH); 
-         $valid->check('password2', 'Validity::length', 8, self::MAX_PASSWORD_LENGTH); 
-         $valid->multipleCheck(['password1', 'password2'], 'Validity::allMatch'); 
-   
-         if ($valid->hasErrors()) { 
-             $_SESSION['admin']['field_errors'] = $valid->getFieldErrors(); 
-             $result = false; 
-         } 
-   
-         if ($_POST['password1'] and $_POST['password1'] === $_POST['password2']) { 
-             // Check password is complex enough 
-             $complexity = Security::passwordComplexity($_POST['password1'], 8, 2, true); 
-             if (!empty($complexity)) { 
-                 $_SESSION['admin']['field_errors']['password1'] = 'Not complex enough'; 
-                 $_SESSION['admin']['field_errors']['password2'] = 'Not complex enough'; 
-                 $result = false; 
-   
-                 Notification::error('Password does not meet complexity requirements:'); 
-                 foreach ($complexity as $c) { 
-                     Notification::error(" \xC2\xA0 \xC2\xA0 " . $c); 
-                 } 
-             } 
-         } 
-   
-         // Check all categories are allowed 
-         if (empty($_POST['categories'])) { 
-             Notification::error('You must choose at least one category'); 
-             $result = false; 
-   
-         } else { 
-             foreach ($_POST['categories'] as $cat_id) { 
-                 if (!$this->manage_cats[$cat_id]) { 
-                     Notification::error('You do not have access to manage category id ' . $cat_id); 
-                     $result = false; 
-                 } 
-             } 
-         } 
-   
-         if (! $result) return false; 
-   
-   
-         // Start transaction 
-         Pdb::transact(); 
-   
-         // Main insert 
-         $update_fields = []; 
-         $update_fields['name'] = $_POST['name']; 
-         $update_fields['username'] = $_POST['username']; 
-         $update_fields['email'] = $_POST['email']; 
-         $update_fields['firstrun'] = 1; 
-         $update_fields['date_added'] = Pdb::now(); 
-         $update_fields['date_modified'] = Pdb::now(); 
-   
-         $item_id = Pdb::insert('operators', $update_fields); 
-   
-         $this->logAdd('operators', $item_id); 
-   
-         AdminAuth::changePassword($_POST['password1'], $item_id); 
-   
-         // Update the categories 
-         $this->updateCategories($item_id, $_POST['categories']); 
-   
-         // Commit 
-         Pdb::commit(); 
-   
-         // Send email, if message is set 
-         $_POST['password'] = $_POST['password1']; 
-         $text = EmailText::getHtml('operator.welcome', $_POST); 
-             $mail = new Email(); 
-             $mail->AddAddress($_POST['email']); 
-             $mail->Subject = 'New operator account created'; 
-             $mail->SkinnedHTML($text); 
-             $mail->Send(); 
-         } 
-   
-         return true; 
-     } 
-   
-   
-     /** 
-     * Pre-render hook for editing 
-     **/ 
-     protected function _editPreRender($view, $item_id) 
-     { 
-         parent::_editPreRender($view, $item_id); 
-   
-         if (AdminAuth::hasDatabaseRecord() and $item_id == AdminAuth::getId()) { 
-             Url::redirect('admin/intro/my_settings'); 
-         } 
-   
-         $view->cats = $this->manage_cats; 
-   
-         foreach ($view->data['categories'] as $cat_id) { 
-             if (!$this->manage_cats[$cat_id]) { 
-                 Notification::error('This operator is in a category you do not have permission to manage - category id ' . $cat_id); 
-                 Url::redirect('admin/intro/operator'); 
-             } 
-         } 
-     } 
-   
-   
-     /** 
-     * Saves the provided POST data the specified record 
-     * 
-     * @param int $item_id The record to update 
-     * @param bool True on success, false on failure 
-     **/ 
-     public function _editSave($item_id) 
-     { 
-         $item_id = (int) $item_id; 
-   
-         if (AdminAuth::hasDatabaseRecord() and $item_id == AdminAuth::getId()) { 
-             Url::redirect('admin/intro/my_settings'); 
-         } 
-   
-         $can_access = AdminPerms::canEditOperator($item_id); 
-         if (!$can_access) return false; 
-   
-         $_SESSION['admin']['field_values'] =-  Validator ::trim($_POST);
 
-         $result = true; 
-   
-         $valid = new Validator($_POST); 
-         $valid->required(['username', 'name', 'email']); 
-         $valid->check('username', 'Validity::length', 0, 50); 
-         $valid->check('username', 'Validity::uniqueValue', 'operators', 'username', $item_id, 'An operator already exists with that username'); 
-         $valid->check('username', 'Validity::regex', '/^[a-zA-Z0-9]+$/'); 
-         $valid->check('name', 'Validity::length', 0, 200); 
-         $valid->check('email', 'Validity::length', 0, 200); 
-         $valid->check('password1', 'Validity::length', 8, self::MAX_PASSWORD_LENGTH); 
-         $valid->check('password2', 'Validity::length', 8, self::MAX_PASSWORD_LENGTH); 
-         $valid->multipleCheck(['password1', 'password2'], 'Validity::allMatch'); 
-   
-         if ($valid->hasErrors()) { 
-             $_SESSION['admin']['field_errors'] = $valid->getFieldErrors(); 
-             $valid->createNotifications(); 
-             $result = false; 
-         } 
-   
-         if ($_POST['password1'] and $_POST['password1'] === $_POST['password2']) { 
-             // Check password is complex enough 
-             $complexity = Security::passwordComplexity($_POST['password1'], 8, 2, true); 
-             if (!empty($complexity)) { 
-                 $_SESSION['admin']['field_errors']['password1'] = 'Not complex enough'; 
-                 $_SESSION['admin']['field_errors']['password2'] = 'Not complex enough'; 
-                 $result = false; 
-   
-                 Notification::error('Password does not meet complexity requirements:'); 
-                 foreach ($complexity as $c) { 
-                     Notification::error(" \xC2\xA0 \xC2\xA0 " . $c); 
-                 } 
-             } 
-         } 
-   
-         // Check all categories are allowed 
-         if (empty($_POST['categories'])) { 
-             Notification::error('You must choose at least one category'); 
-             $result = false; 
-   
-         } else { 
-             foreach ($_POST['categories'] as $cat_id) { 
-                 if (!$this->manage_cats[$cat_id]) { 
-                     Notification::error('You do not have access to manage category id ' . $cat_id); 
-                     $result = false; 
-                 } 
-             } 
-         } 
-   
-         if (! $result) return false; 
-   
-         // Start transaction 
-         Pdb::transact(); 
-   
-         // Update item 
-         $update_fields = array(); 
-         $update_fields['name'] = $_POST['name']; 
-         $update_fields['email'] = $_POST['email']; 
-         $update_fields['username'] = $_POST['username']; 
-         $update_fields['date_modified'] = Pdb::now(); 
-   
-         $logdata = $this->loadRecord('operators', $item_id); 
-   
-         Pdb::update('operators', $update_fields, ['id' => $item_id]); 
-   
-         $this->logEdit('operators', $item_id, $logdata); 
-   
-         if ($_POST['password1']) { 
-             AdminAuth::changePassword($_POST['password1'], $item_id); 
-             $this->logAction('operators', $item_id, 'Change password'); 
-         } 
-   
-         // Update the categories 
-         $this->updateCategories($item_id, $_POST['categories']); 
-   
-         // Commit 
-         Pdb::commit(); 
-   
-         return true; 
-     } 
-   
-   
-     /** 
-      * Prevents deletion of accounts when the user doesn't have access, and deletion of self 
-      * @param int $item_id The record to delete 
-      * @return void 
-      * @throws Exception if deletion not allowed 
-      */ 
-     public function _deletePreSave($item_id) 
-     { 
-         $item_id = (int) $item_id; 
-   
-         if (!AdminPerms::canEditOperator($item_id)) { 
-             throw new Exception('Permission denied'); 
-         } 
-   
-         if ($item_id == AdminAuth::getLocalId()) { 
-             throw new Exception('You cannot delete your own record'); 
-         } 
-     } 
-   
- } 
-   
-   
-