@@ -29,23 +29,23 @@ |
||
| 29 | 29 | */ |
| 30 | 30 | class i18nSchema extends CakeSchema { |
| 31 | 31 | |
| 32 | - public $name = 'i18n'; |
|
| 32 | + public $name = 'i18n'; |
|
| 33 | 33 | |
| 34 | - public function before($event = array()) { |
|
| 35 | - return true; |
|
| 36 | - } |
|
| 34 | + public function before($event = array()) { |
|
| 35 | + return true; |
|
| 36 | + } |
|
| 37 | 37 | |
| 38 | - public function after($event = array()) { |
|
| 39 | - } |
|
| 38 | + public function after($event = array()) { |
|
| 39 | + } |
|
| 40 | 40 | |
| 41 | - public $i18n = array( |
|
| 42 | - 'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'), |
|
| 43 | - 'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'), |
|
| 44 | - 'model' => array('type'=>'string', 'null' => false, 'key' => 'index'), |
|
| 45 | - 'foreign_key' => array('type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'), |
|
| 46 | - 'field' => array('type'=>'string', 'null' => false, 'key' => 'index'), |
|
| 47 | - 'content' => array('type'=>'text', 'null' => true, 'default' => NULL), |
|
| 48 | - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'locale' => array('column' => 'locale', 'unique' => 0), 'model' => array('column' => 'model', 'unique' => 0), 'row_id' => array('column' => 'foreign_key', 'unique' => 0), 'field' => array('column' => 'field', 'unique' => 0)) |
|
| 49 | - ); |
|
| 41 | + public $i18n = array( |
|
| 42 | + 'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'), |
|
| 43 | + 'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'), |
|
| 44 | + 'model' => array('type'=>'string', 'null' => false, 'key' => 'index'), |
|
| 45 | + 'foreign_key' => array('type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'), |
|
| 46 | + 'field' => array('type'=>'string', 'null' => false, 'key' => 'index'), |
|
| 47 | + 'content' => array('type'=>'text', 'null' => true, 'default' => NULL), |
|
| 48 | + 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'locale' => array('column' => 'locale', 'unique' => 0), 'model' => array('column' => 'model', 'unique' => 0), 'row_id' => array('column' => 'foreign_key', 'unique' => 0), 'field' => array('column' => 'field', 'unique' => 0)) |
|
| 49 | + ); |
|
| 50 | 50 | |
| 51 | 51 | } |
@@ -20,7 +20,7 @@ discard block |
||
| 20 | 20 | * Use the DS to separate the directories in other defines |
| 21 | 21 | */ |
| 22 | 22 | if (!defined('DS')) { |
| 23 | - define('DS', DIRECTORY_SEPARATOR); |
|
| 23 | + define('DS', DIRECTORY_SEPARATOR); |
|
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | /** |
@@ -33,21 +33,21 @@ discard block |
||
| 33 | 33 | * The full path to the directory which holds "app", WITHOUT a trailing DS. |
| 34 | 34 | */ |
| 35 | 35 | if (!defined('ROOT')) { |
| 36 | - define('ROOT', dirname(dirname(dirname(__FILE__)))); |
|
| 36 | + define('ROOT', dirname(dirname(dirname(__FILE__)))); |
|
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | /** |
| 40 | 40 | * The actual directory name for the "app". |
| 41 | 41 | */ |
| 42 | 42 | if (!defined('APP_DIR')) { |
| 43 | - define('APP_DIR', basename(dirname(dirname(__FILE__)))); |
|
| 43 | + define('APP_DIR', basename(dirname(dirname(__FILE__)))); |
|
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | /** |
| 47 | 47 | * Config Directory |
| 48 | 48 | */ |
| 49 | 49 | if (!defined('CONFIG')) { |
| 50 | - define('CONFIG', ROOT . DS . APP_DIR . DS . 'Config' . DS); |
|
| 50 | + define('CONFIG', ROOT . DS . APP_DIR . DS . 'Config' . DS); |
|
| 51 | 51 | } |
| 52 | 52 | |
| 53 | 53 | /** |
@@ -73,7 +73,7 @@ discard block |
||
| 73 | 73 | $vendorPath = ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; |
| 74 | 74 | $dispatcher = 'Cake' . DS . 'Console' . DS . 'ShellDispatcher.php'; |
| 75 | 75 | if (!defined('CAKE_CORE_INCLUDE_PATH') && file_exists($vendorPath . DS . $dispatcher)) { |
| 76 | - define('CAKE_CORE_INCLUDE_PATH', $vendorPath); |
|
| 76 | + define('CAKE_CORE_INCLUDE_PATH', $vendorPath); |
|
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /** |
@@ -81,38 +81,38 @@ discard block |
||
| 81 | 81 | * Change at your own risk. |
| 82 | 82 | */ |
| 83 | 83 | if (!defined('WEBROOT_DIR')) { |
| 84 | - define('WEBROOT_DIR', basename(dirname(__FILE__))); |
|
| 84 | + define('WEBROOT_DIR', basename(dirname(__FILE__))); |
|
| 85 | 85 | } |
| 86 | 86 | if (!defined('WWW_ROOT')) { |
| 87 | - define('WWW_ROOT', dirname(__FILE__) . DS); |
|
| 87 | + define('WWW_ROOT', dirname(__FILE__) . DS); |
|
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | // For the built-in server |
| 91 | 91 | if (PHP_SAPI === 'cli-server') { |
| 92 | - if ($_SERVER['PHP_SELF'] !== '/' . basename(__FILE__) && file_exists(WWW_ROOT . $_SERVER['PHP_SELF'])) { |
|
| 93 | - return false; |
|
| 94 | - } |
|
| 95 | - $_SERVER['PHP_SELF'] = '/' . basename(__FILE__); |
|
| 92 | + if ($_SERVER['PHP_SELF'] !== '/' . basename(__FILE__) && file_exists(WWW_ROOT . $_SERVER['PHP_SELF'])) { |
|
| 93 | + return false; |
|
| 94 | + } |
|
| 95 | + $_SERVER['PHP_SELF'] = '/' . basename(__FILE__); |
|
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | if (!defined('CAKE_CORE_INCLUDE_PATH')) { |
| 99 | - if (function_exists('ini_set')) { |
|
| 100 | - ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); |
|
| 101 | - } |
|
| 102 | - if (!include 'Cake' . DS . 'bootstrap.php') { |
|
| 103 | - $failed = true; |
|
| 104 | - } |
|
| 99 | + if (function_exists('ini_set')) { |
|
| 100 | + ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); |
|
| 101 | + } |
|
| 102 | + if (!include 'Cake' . DS . 'bootstrap.php') { |
|
| 103 | + $failed = true; |
|
| 104 | + } |
|
| 105 | 105 | } elseif (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') { |
| 106 | - $failed = true; |
|
| 106 | + $failed = true; |
|
| 107 | 107 | } |
| 108 | 108 | if (!empty($failed)) { |
| 109 | - trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); |
|
| 109 | + trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); |
|
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | App::uses('Dispatcher', 'Routing'); |
| 113 | 113 | |
| 114 | 114 | $Dispatcher = new Dispatcher(); |
| 115 | 115 | $Dispatcher->dispatch( |
| 116 | - new CakeRequest(), |
|
| 117 | - new CakeResponse() |
|
| 116 | + new CakeRequest(), |
|
| 117 | + new CakeResponse() |
|
| 118 | 118 | ); |
@@ -23,7 +23,7 @@ discard block |
||
| 23 | 23 | * Use the DS to separate the directories in other defines |
| 24 | 24 | */ |
| 25 | 25 | if (!defined('DS')) { |
| 26 | - define('DS', DIRECTORY_SEPARATOR); |
|
| 26 | + define('DS', DIRECTORY_SEPARATOR); |
|
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | /** |
@@ -36,21 +36,21 @@ discard block |
||
| 36 | 36 | * The full path to the directory which holds "app", WITHOUT a trailing DS. |
| 37 | 37 | */ |
| 38 | 38 | if (!defined('ROOT')) { |
| 39 | - define('ROOT', dirname(dirname(dirname(__FILE__)))); |
|
| 39 | + define('ROOT', dirname(dirname(dirname(__FILE__)))); |
|
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | /** |
| 43 | 43 | * The actual directory name for the "app". |
| 44 | 44 | */ |
| 45 | 45 | if (!defined('APP_DIR')) { |
| 46 | - define('APP_DIR', basename(dirname(dirname(__FILE__)))); |
|
| 46 | + define('APP_DIR', basename(dirname(dirname(__FILE__)))); |
|
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | /** |
| 50 | 50 | * Config Directory |
| 51 | 51 | */ |
| 52 | 52 | if (!defined('CONFIG')) { |
| 53 | - define('CONFIG', ROOT . DS . APP_DIR . DS . 'Config' . DS); |
|
| 53 | + define('CONFIG', ROOT . DS . APP_DIR . DS . 'Config' . DS); |
|
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | /** |
@@ -73,7 +73,7 @@ discard block |
||
| 73 | 73 | $vendorPath = ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; |
| 74 | 74 | $dispatcher = 'Cake' . DS . 'Console' . DS . 'ShellDispatcher.php'; |
| 75 | 75 | if (!defined('CAKE_CORE_INCLUDE_PATH') && file_exists($vendorPath . DS . $dispatcher)) { |
| 76 | - define('CAKE_CORE_INCLUDE_PATH', $vendorPath); |
|
| 76 | + define('CAKE_CORE_INCLUDE_PATH', $vendorPath); |
|
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /** |
@@ -81,30 +81,30 @@ discard block |
||
| 81 | 81 | * Change at your own risk. |
| 82 | 82 | */ |
| 83 | 83 | if (!defined('WEBROOT_DIR')) { |
| 84 | - define('WEBROOT_DIR', basename(dirname(__FILE__))); |
|
| 84 | + define('WEBROOT_DIR', basename(dirname(__FILE__))); |
|
| 85 | 85 | } |
| 86 | 86 | if (!defined('WWW_ROOT')) { |
| 87 | - define('WWW_ROOT', dirname(__FILE__) . DS); |
|
| 87 | + define('WWW_ROOT', dirname(__FILE__) . DS); |
|
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | if (!defined('CAKE_CORE_INCLUDE_PATH')) { |
| 91 | - if (function_exists('ini_set')) { |
|
| 92 | - ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); |
|
| 93 | - } |
|
| 94 | - if (!include 'Cake' . DS . 'bootstrap.php') { |
|
| 95 | - $failed = true; |
|
| 96 | - } |
|
| 91 | + if (function_exists('ini_set')) { |
|
| 92 | + ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); |
|
| 93 | + } |
|
| 94 | + if (!include 'Cake' . DS . 'bootstrap.php') { |
|
| 95 | + $failed = true; |
|
| 96 | + } |
|
| 97 | 97 | } else { |
| 98 | - if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') { |
|
| 99 | - $failed = true; |
|
| 100 | - } |
|
| 98 | + if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') { |
|
| 99 | + $failed = true; |
|
| 100 | + } |
|
| 101 | 101 | } |
| 102 | 102 | if (!empty($failed)) { |
| 103 | - trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/test.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); |
|
| 103 | + trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/test.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); |
|
| 104 | 104 | } |
| 105 | 105 | |
| 106 | 106 | if (Configure::read('debug') < 1) { |
| 107 | - throw new NotFoundException(__d('cake_dev', 'Debug setting does not allow access to this URL.')); |
|
| 107 | + throw new NotFoundException(__d('cake_dev', 'Debug setting does not allow access to this URL.')); |
|
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | require_once CAKE . 'TestSuite' . DS . 'CakeTestSuiteDispatcher.php'; |
@@ -1,171 +1,171 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | - use Saito\User\Auth; |
|
| 4 | - use Saito\User\SaitoUser; |
|
| 5 | - |
|
| 6 | - class DummyDataShell extends AppShell { |
|
| 7 | - |
|
| 8 | - public $uses = ['Entry', 'User']; |
|
| 9 | - |
|
| 10 | - protected $_Categories = null; |
|
| 11 | - |
|
| 12 | - protected $_Users = null; |
|
| 13 | - |
|
| 14 | - protected $_text = null; |
|
| 15 | - |
|
| 16 | - protected $_Threads = []; |
|
| 17 | - |
|
| 18 | - protected $_users = ['aaron', 'Alex', 'Amy', 'Ana-Lucia', 'Anthony', 'Ben', |
|
| 19 | - 'Bernard', 'Boone', 'Carmen', 'Carole', 'Charles', 'Charlie', 'Charlotte', |
|
| 20 | - 'Christian', 'Claire', 'Daniel', 'Danielle', 'Desmond', 'Dogen', 'Eko', |
|
| 21 | - 'Eloise', 'Ethan', 'Frank', 'Frogurt', 'George', 'Gina', 'Horace', 'Hugo', |
|
| 22 | - 'Ilana', 'Jack', 'Jacob', 'James', 'Jin', 'John', 'Juliet', 'Kate', |
|
| 23 | - 'Kelvin', 'Liam', 'Libby', 'Martin', 'Maninbla', 'Michael', 'Michelle', |
|
| 24 | - 'Miles', 'Nadia', 'Naomi', 'Nikki', 'Omar', 'Paulo', 'Penny', 'Pierre', |
|
| 25 | - 'Richard', 'Sarah', 'Sayid', 'Shannon', 'Stuart', 'Sun', 'Teresa', 'Tom', |
|
| 26 | - 'walt']; |
|
| 27 | - |
|
| 28 | - public function main() { |
|
| 29 | - $this->user(); |
|
| 30 | - $this->generate(); |
|
| 31 | - } |
|
| 32 | - |
|
| 33 | - public function generate() { |
|
| 34 | - $nPostings = (int)$this->in('Number of postings to generate?', null, 100); |
|
| 35 | - if ($nPostings === 0) { |
|
| 36 | - return; |
|
| 37 | - } |
|
| 38 | - $ratio = (int)$this->in('Average answers per thread?', null, 10); |
|
| 39 | - $seed = $nPostings / $ratio; |
|
| 40 | - |
|
| 41 | - new Saito\Markup\Settings([ |
|
| 42 | - 'hashBaseUrl' => 'entries/view/', |
|
| 43 | - 'atBaseUrl' => 'users/name/', |
|
| 44 | - 'server' => Router::fullBaseUrl(), |
|
| 45 | - 'webroot' => Router::fullBaseUrl() |
|
| 46 | - ]); |
|
| 47 | - $this->Entry->SharedObjects['CurrentUser'] = new SaitoUserDummy(); |
|
| 48 | - |
|
| 49 | - for ($i = 0; $i < $nPostings; $i++) { |
|
| 50 | - $newThread = $i < $seed; |
|
| 51 | - |
|
| 52 | - $user = $this->_randomUser(); |
|
| 53 | - $this->Entry->CurrentUser->setSettings($user); |
|
| 54 | - |
|
| 55 | - $entry = [ |
|
| 56 | - 'subject' => $i, |
|
| 57 | - 'text' => rand(0, 1) ? $this->_randomText() : '', |
|
| 58 | - 'user_id' => $user['id'] |
|
| 59 | - ]; |
|
| 60 | - if ($newThread) { |
|
| 61 | - $entry['category'] = $this->_randomCategory(); |
|
| 62 | - } else { |
|
| 63 | - $entry['pid'] = array_rand($this->_Threads); |
|
| 64 | - } |
|
| 65 | - $entry = $this->Entry->createPosting(['Entry' => $entry]); |
|
| 66 | - if (empty($entry)) { |
|
| 67 | - throw new RuntimeException('Could not create entry: ' . $entry); |
|
| 68 | - } |
|
| 69 | - |
|
| 70 | - $this->_progress($i, $nPostings); |
|
| 71 | - |
|
| 72 | - $id = $entry['Entry']['id']; |
|
| 73 | - $this->_Threads[$id] = $id; |
|
| 74 | - } |
|
| 75 | - |
|
| 76 | - $this->out(); |
|
| 77 | - $this->out("Generated $i postings."); |
|
| 78 | - } |
|
| 79 | - |
|
| 80 | - public function user() { |
|
| 81 | - $max = count($this->_users); |
|
| 82 | - $n = (int)$this->in("Number of users to generate (max: $max)?", null, 0); |
|
| 83 | - if ($n === 0) { |
|
| 84 | - return; |
|
| 85 | - } |
|
| 86 | - if ($n > $max) { |
|
| 87 | - $n = $max; |
|
| 88 | - } |
|
| 89 | - $users = array_rand($this->_users, $n); |
|
| 90 | - $i = 0; |
|
| 91 | - foreach ($users as $user) { |
|
| 92 | - $name = $this->_users[$user]; |
|
| 93 | - $data = [ |
|
| 94 | - 'User' => [ |
|
| 95 | - 'username' => $name, |
|
| 96 | - 'password' => 'test', |
|
| 97 | - 'password_confirm' => 'test', |
|
| 98 | - 'user_email' => "[email protected]" |
|
| 99 | - ] |
|
| 100 | - ]; |
|
| 101 | - $this->User->register($data, true); |
|
| 102 | - $this->_progress($i++, $n); |
|
| 103 | - } |
|
| 104 | - |
|
| 105 | - $this->out(); |
|
| 106 | - $this->out("Generated $i users."); |
|
| 107 | - } |
|
| 108 | - |
|
| 109 | - protected function _progress($i, $off) { |
|
| 110 | - if ($i < 1) { |
|
| 111 | - return; |
|
| 112 | - } |
|
| 113 | - $this->out('.', 0); |
|
| 114 | - if ($i > 1 && !($i % 50)) { |
|
| 115 | - $percent = (int)floor($i / $off * 100); |
|
| 116 | - $this->out(sprintf(' %3s%%', $percent), 1); |
|
| 117 | - } |
|
| 118 | - } |
|
| 119 | - |
|
| 120 | - protected function _randomCategory() { |
|
| 121 | - if ($this->_Categories === null) { |
|
| 122 | - $this->_Categories = $this->Entry->Category->find('all', |
|
| 123 | - ['recursive' => 0, 'fields' => ['id']]); |
|
| 124 | - } |
|
| 125 | - $id = array_rand($this->_Categories); |
|
| 126 | - return $this->_Categories[$id]['Category']['id']; |
|
| 127 | - } |
|
| 128 | - |
|
| 129 | - protected function _randomUser() { |
|
| 130 | - if ($this->_Users === null) { |
|
| 131 | - $this->_Users = $this->User->find('all', |
|
| 132 | - ['recursive' => -1, 'conditions' => ['activate_code' => 0]]); |
|
| 133 | - } |
|
| 134 | - $id = array_rand($this->_Users); |
|
| 135 | - return $this->_Users[$id]['User']; |
|
| 136 | - } |
|
| 137 | - |
|
| 138 | - protected function _randomText() { |
|
| 139 | - if (empty($this->_text)) { |
|
| 140 | - $this->_text = file_get_contents('http://loripsum.net/api/short/plaintext'); |
|
| 141 | - } |
|
| 142 | - return $this->_text; |
|
| 143 | - } |
|
| 144 | - |
|
| 145 | - } |
|
| 146 | - |
|
| 147 | - class SaitoUserDummy extends SaitoUser { |
|
| 148 | - |
|
| 149 | - public function __construct($settings = null) { |
|
| 150 | - parent::__construct($settings); |
|
| 151 | - $this->Categories = new Auth\CategoryAuthorization($this); |
|
| 152 | - } |
|
| 153 | - |
|
| 154 | - public function getMaxAccession() { |
|
| 155 | - return 2; |
|
| 156 | - } |
|
| 157 | - |
|
| 158 | - public function isLoggedIn() { |
|
| 159 | - return true; |
|
| 160 | - } |
|
| 161 | - |
|
| 162 | - public function isAdmin() { |
|
| 163 | - return true; |
|
| 164 | - } |
|
| 165 | - |
|
| 166 | - public function hasBookmarked() { |
|
| 167 | - return false; |
|
| 168 | - } |
|
| 169 | - |
|
| 170 | - } |
|
| 3 | + use Saito\User\Auth; |
|
| 4 | + use Saito\User\SaitoUser; |
|
| 5 | + |
|
| 6 | + class DummyDataShell extends AppShell { |
|
| 7 | + |
|
| 8 | + public $uses = ['Entry', 'User']; |
|
| 9 | + |
|
| 10 | + protected $_Categories = null; |
|
| 11 | + |
|
| 12 | + protected $_Users = null; |
|
| 13 | + |
|
| 14 | + protected $_text = null; |
|
| 15 | + |
|
| 16 | + protected $_Threads = []; |
|
| 17 | + |
|
| 18 | + protected $_users = ['aaron', 'Alex', 'Amy', 'Ana-Lucia', 'Anthony', 'Ben', |
|
| 19 | + 'Bernard', 'Boone', 'Carmen', 'Carole', 'Charles', 'Charlie', 'Charlotte', |
|
| 20 | + 'Christian', 'Claire', 'Daniel', 'Danielle', 'Desmond', 'Dogen', 'Eko', |
|
| 21 | + 'Eloise', 'Ethan', 'Frank', 'Frogurt', 'George', 'Gina', 'Horace', 'Hugo', |
|
| 22 | + 'Ilana', 'Jack', 'Jacob', 'James', 'Jin', 'John', 'Juliet', 'Kate', |
|
| 23 | + 'Kelvin', 'Liam', 'Libby', 'Martin', 'Maninbla', 'Michael', 'Michelle', |
|
| 24 | + 'Miles', 'Nadia', 'Naomi', 'Nikki', 'Omar', 'Paulo', 'Penny', 'Pierre', |
|
| 25 | + 'Richard', 'Sarah', 'Sayid', 'Shannon', 'Stuart', 'Sun', 'Teresa', 'Tom', |
|
| 26 | + 'walt']; |
|
| 27 | + |
|
| 28 | + public function main() { |
|
| 29 | + $this->user(); |
|
| 30 | + $this->generate(); |
|
| 31 | + } |
|
| 32 | + |
|
| 33 | + public function generate() { |
|
| 34 | + $nPostings = (int)$this->in('Number of postings to generate?', null, 100); |
|
| 35 | + if ($nPostings === 0) { |
|
| 36 | + return; |
|
| 37 | + } |
|
| 38 | + $ratio = (int)$this->in('Average answers per thread?', null, 10); |
|
| 39 | + $seed = $nPostings / $ratio; |
|
| 40 | + |
|
| 41 | + new Saito\Markup\Settings([ |
|
| 42 | + 'hashBaseUrl' => 'entries/view/', |
|
| 43 | + 'atBaseUrl' => 'users/name/', |
|
| 44 | + 'server' => Router::fullBaseUrl(), |
|
| 45 | + 'webroot' => Router::fullBaseUrl() |
|
| 46 | + ]); |
|
| 47 | + $this->Entry->SharedObjects['CurrentUser'] = new SaitoUserDummy(); |
|
| 48 | + |
|
| 49 | + for ($i = 0; $i < $nPostings; $i++) { |
|
| 50 | + $newThread = $i < $seed; |
|
| 51 | + |
|
| 52 | + $user = $this->_randomUser(); |
|
| 53 | + $this->Entry->CurrentUser->setSettings($user); |
|
| 54 | + |
|
| 55 | + $entry = [ |
|
| 56 | + 'subject' => $i, |
|
| 57 | + 'text' => rand(0, 1) ? $this->_randomText() : '', |
|
| 58 | + 'user_id' => $user['id'] |
|
| 59 | + ]; |
|
| 60 | + if ($newThread) { |
|
| 61 | + $entry['category'] = $this->_randomCategory(); |
|
| 62 | + } else { |
|
| 63 | + $entry['pid'] = array_rand($this->_Threads); |
|
| 64 | + } |
|
| 65 | + $entry = $this->Entry->createPosting(['Entry' => $entry]); |
|
| 66 | + if (empty($entry)) { |
|
| 67 | + throw new RuntimeException('Could not create entry: ' . $entry); |
|
| 68 | + } |
|
| 69 | + |
|
| 70 | + $this->_progress($i, $nPostings); |
|
| 71 | + |
|
| 72 | + $id = $entry['Entry']['id']; |
|
| 73 | + $this->_Threads[$id] = $id; |
|
| 74 | + } |
|
| 75 | + |
|
| 76 | + $this->out(); |
|
| 77 | + $this->out("Generated $i postings."); |
|
| 78 | + } |
|
| 79 | + |
|
| 80 | + public function user() { |
|
| 81 | + $max = count($this->_users); |
|
| 82 | + $n = (int)$this->in("Number of users to generate (max: $max)?", null, 0); |
|
| 83 | + if ($n === 0) { |
|
| 84 | + return; |
|
| 85 | + } |
|
| 86 | + if ($n > $max) { |
|
| 87 | + $n = $max; |
|
| 88 | + } |
|
| 89 | + $users = array_rand($this->_users, $n); |
|
| 90 | + $i = 0; |
|
| 91 | + foreach ($users as $user) { |
|
| 92 | + $name = $this->_users[$user]; |
|
| 93 | + $data = [ |
|
| 94 | + 'User' => [ |
|
| 95 | + 'username' => $name, |
|
| 96 | + 'password' => 'test', |
|
| 97 | + 'password_confirm' => 'test', |
|
| 98 | + 'user_email' => "[email protected]" |
|
| 99 | + ] |
|
| 100 | + ]; |
|
| 101 | + $this->User->register($data, true); |
|
| 102 | + $this->_progress($i++, $n); |
|
| 103 | + } |
|
| 104 | + |
|
| 105 | + $this->out(); |
|
| 106 | + $this->out("Generated $i users."); |
|
| 107 | + } |
|
| 108 | + |
|
| 109 | + protected function _progress($i, $off) { |
|
| 110 | + if ($i < 1) { |
|
| 111 | + return; |
|
| 112 | + } |
|
| 113 | + $this->out('.', 0); |
|
| 114 | + if ($i > 1 && !($i % 50)) { |
|
| 115 | + $percent = (int)floor($i / $off * 100); |
|
| 116 | + $this->out(sprintf(' %3s%%', $percent), 1); |
|
| 117 | + } |
|
| 118 | + } |
|
| 119 | + |
|
| 120 | + protected function _randomCategory() { |
|
| 121 | + if ($this->_Categories === null) { |
|
| 122 | + $this->_Categories = $this->Entry->Category->find('all', |
|
| 123 | + ['recursive' => 0, 'fields' => ['id']]); |
|
| 124 | + } |
|
| 125 | + $id = array_rand($this->_Categories); |
|
| 126 | + return $this->_Categories[$id]['Category']['id']; |
|
| 127 | + } |
|
| 128 | + |
|
| 129 | + protected function _randomUser() { |
|
| 130 | + if ($this->_Users === null) { |
|
| 131 | + $this->_Users = $this->User->find('all', |
|
| 132 | + ['recursive' => -1, 'conditions' => ['activate_code' => 0]]); |
|
| 133 | + } |
|
| 134 | + $id = array_rand($this->_Users); |
|
| 135 | + return $this->_Users[$id]['User']; |
|
| 136 | + } |
|
| 137 | + |
|
| 138 | + protected function _randomText() { |
|
| 139 | + if (empty($this->_text)) { |
|
| 140 | + $this->_text = file_get_contents('http://loripsum.net/api/short/plaintext'); |
|
| 141 | + } |
|
| 142 | + return $this->_text; |
|
| 143 | + } |
|
| 144 | + |
|
| 145 | + } |
|
| 146 | + |
|
| 147 | + class SaitoUserDummy extends SaitoUser { |
|
| 148 | + |
|
| 149 | + public function __construct($settings = null) { |
|
| 150 | + parent::__construct($settings); |
|
| 151 | + $this->Categories = new Auth\CategoryAuthorization($this); |
|
| 152 | + } |
|
| 153 | + |
|
| 154 | + public function getMaxAccession() { |
|
| 155 | + return 2; |
|
| 156 | + } |
|
| 157 | + |
|
| 158 | + public function isLoggedIn() { |
|
| 159 | + return true; |
|
| 160 | + } |
|
| 161 | + |
|
| 162 | + public function isAdmin() { |
|
| 163 | + return true; |
|
| 164 | + } |
|
| 165 | + |
|
| 166 | + public function hasBookmarked() { |
|
| 167 | + return false; |
|
| 168 | + } |
|
| 169 | + |
|
| 170 | + } |
|
| 171 | 171 | |
@@ -1,87 +1,87 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | - class SiegeShell extends AppShell { |
|
| 3 | + class SiegeShell extends AppShell { |
|
| 4 | 4 | |
| 5 | - public $uses = [ |
|
| 6 | - 'Entry' |
|
| 7 | - ]; |
|
| 5 | + public $uses = [ |
|
| 6 | + 'Entry' |
|
| 7 | + ]; |
|
| 8 | 8 | |
| 9 | - protected $_prefix = '$(HOST)/'; |
|
| 9 | + protected $_prefix = '$(HOST)/'; |
|
| 10 | 10 | |
| 11 | - public function main() { |
|
| 12 | - $out = []; |
|
| 13 | - $base = rtrim($this->args[0], '/'); |
|
| 14 | - $in = $this->in('Base URL is: ' . $base, ['y', 'n'], 'y'); |
|
| 15 | - if ($in !== 'y') { |
|
| 16 | - $this->out('Aborting.'); |
|
| 17 | - return; |
|
| 18 | - } |
|
| 19 | - $out[] = 'HOST=' . $base; |
|
| 20 | - $this->_generateEntriesIndex($out); |
|
| 21 | - $this->_generateEntriesMix($out); |
|
| 22 | - $this->_generateEntriesView($out); |
|
| 23 | - $this->_siege($out); |
|
| 24 | - } |
|
| 11 | + public function main() { |
|
| 12 | + $out = []; |
|
| 13 | + $base = rtrim($this->args[0], '/'); |
|
| 14 | + $in = $this->in('Base URL is: ' . $base, ['y', 'n'], 'y'); |
|
| 15 | + if ($in !== 'y') { |
|
| 16 | + $this->out('Aborting.'); |
|
| 17 | + return; |
|
| 18 | + } |
|
| 19 | + $out[] = 'HOST=' . $base; |
|
| 20 | + $this->_generateEntriesIndex($out); |
|
| 21 | + $this->_generateEntriesMix($out); |
|
| 22 | + $this->_generateEntriesView($out); |
|
| 23 | + $this->_siege($out); |
|
| 24 | + } |
|
| 25 | 25 | |
| 26 | - public function getOptionParser() { |
|
| 27 | - $parser = parent::getOptionParser(); |
|
| 28 | - $parser->addArgument('url', |
|
| 29 | - [ |
|
| 30 | - 'help' => 'Saito base URL', |
|
| 31 | - 'required' => true |
|
| 32 | - ]); |
|
| 33 | - return $parser; |
|
| 34 | - } |
|
| 26 | + public function getOptionParser() { |
|
| 27 | + $parser = parent::getOptionParser(); |
|
| 28 | + $parser->addArgument('url', |
|
| 29 | + [ |
|
| 30 | + 'help' => 'Saito base URL', |
|
| 31 | + 'required' => true |
|
| 32 | + ]); |
|
| 33 | + return $parser; |
|
| 34 | + } |
|
| 35 | 35 | |
| 36 | - protected function _siege(&$out) { |
|
| 37 | - $urlFilePath = TMP . 'url.txt'; |
|
| 38 | - $this->_cleanup($urlFilePath); |
|
| 39 | - $this->createFile($urlFilePath, implode("\n", $out)); |
|
| 40 | - $command = 'siege -R ' . APP . '..' . DS . ".siegerc -f $urlFilePath"; |
|
| 41 | - $this->out('<info>Running: ' . $command . '</info>', 1, 'info'); |
|
| 42 | - exec($command); |
|
| 43 | - } |
|
| 36 | + protected function _siege(&$out) { |
|
| 37 | + $urlFilePath = TMP . 'url.txt'; |
|
| 38 | + $this->_cleanup($urlFilePath); |
|
| 39 | + $this->createFile($urlFilePath, implode("\n", $out)); |
|
| 40 | + $command = 'siege -R ' . APP . '..' . DS . ".siegerc -f $urlFilePath"; |
|
| 41 | + $this->out('<info>Running: ' . $command . '</info>', 1, 'info'); |
|
| 42 | + exec($command); |
|
| 43 | + } |
|
| 44 | 44 | |
| 45 | - protected function _cleanup($urlFilePath) { |
|
| 46 | - if (file_exists($urlFilePath)) { |
|
| 47 | - unlink($urlFilePath); |
|
| 48 | - } |
|
| 49 | - } |
|
| 45 | + protected function _cleanup($urlFilePath) { |
|
| 46 | + if (file_exists($urlFilePath)) { |
|
| 47 | + unlink($urlFilePath); |
|
| 48 | + } |
|
| 49 | + } |
|
| 50 | 50 | |
| 51 | - protected function _generateEntriesIndex(&$out) { |
|
| 52 | - for ($i = 0; $i < 400; $i++) { |
|
| 53 | - $out[] = $this->_prefix . 'entries/index/page:' . rand(1, 2); |
|
| 54 | - } |
|
| 55 | - for ($i = 0; $i < 400; $i++) { |
|
| 56 | - $out[] = $this->_prefix . 'entries/index/page:' . rand(5, 10); |
|
| 57 | - } |
|
| 58 | - } |
|
| 51 | + protected function _generateEntriesIndex(&$out) { |
|
| 52 | + for ($i = 0; $i < 400; $i++) { |
|
| 53 | + $out[] = $this->_prefix . 'entries/index/page:' . rand(1, 2); |
|
| 54 | + } |
|
| 55 | + for ($i = 0; $i < 400; $i++) { |
|
| 56 | + $out[] = $this->_prefix . 'entries/index/page:' . rand(5, 10); |
|
| 57 | + } |
|
| 58 | + } |
|
| 59 | 59 | |
| 60 | - protected function _generateEntriesMix(&$out) { |
|
| 61 | - $entries = $this->Entry->find('all', |
|
| 62 | - [ |
|
| 63 | - 'fields' => ['Entry.id'], |
|
| 64 | - 'conditions' => ['Entry.pid' => 0, 'Category.accession' => 1], |
|
| 65 | - 'limit' => '500' |
|
| 66 | - ]); |
|
| 60 | + protected function _generateEntriesMix(&$out) { |
|
| 61 | + $entries = $this->Entry->find('all', |
|
| 62 | + [ |
|
| 63 | + 'fields' => ['Entry.id'], |
|
| 64 | + 'conditions' => ['Entry.pid' => 0, 'Category.accession' => 1], |
|
| 65 | + 'limit' => '500' |
|
| 66 | + ]); |
|
| 67 | 67 | |
| 68 | - foreach ($entries as $entry) { |
|
| 69 | - $out[] = $this->_prefix . 'entries/mix/' . $entry['Entry']['id']; |
|
| 70 | - } |
|
| 71 | - } |
|
| 68 | + foreach ($entries as $entry) { |
|
| 69 | + $out[] = $this->_prefix . 'entries/mix/' . $entry['Entry']['id']; |
|
| 70 | + } |
|
| 71 | + } |
|
| 72 | 72 | |
| 73 | - protected function _generateEntriesView(&$out) { |
|
| 74 | - $entries = $this->Entry->find('all', |
|
| 75 | - [ |
|
| 76 | - 'fields' => ['Entry.id'], |
|
| 77 | - 'conditions' => ['Category.accession' => 1], |
|
| 78 | - 'limit' => '1000' |
|
| 79 | - ]); |
|
| 73 | + protected function _generateEntriesView(&$out) { |
|
| 74 | + $entries = $this->Entry->find('all', |
|
| 75 | + [ |
|
| 76 | + 'fields' => ['Entry.id'], |
|
| 77 | + 'conditions' => ['Category.accession' => 1], |
|
| 78 | + 'limit' => '1000' |
|
| 79 | + ]); |
|
| 80 | 80 | |
| 81 | - foreach ($entries as $entry) { |
|
| 82 | - $out[] = $this->_prefix . 'entries/view/' . $entry['Entry']['id']; |
|
| 83 | - } |
|
| 84 | - } |
|
| 81 | + foreach ($entries as $entry) { |
|
| 82 | + $out[] = $this->_prefix . 'entries/view/' . $entry['Entry']['id']; |
|
| 83 | + } |
|
| 84 | + } |
|
| 85 | 85 | |
| 86 | - } |
|
| 86 | + } |
|
| 87 | 87 | |
@@ -18,29 +18,29 @@ |
||
| 18 | 18 | */ |
| 19 | 19 | |
| 20 | 20 | if (!defined('DS')) { |
| 21 | - define('DS', DIRECTORY_SEPARATOR); |
|
| 21 | + define('DS', DIRECTORY_SEPARATOR); |
|
| 22 | 22 | } |
| 23 | 23 | |
| 24 | 24 | $dispatcher = 'Cake' . DS . 'Console' . DS . 'ShellDispatcher.php'; |
| 25 | 25 | |
| 26 | 26 | if (function_exists('ini_set')) { |
| 27 | - $root = dirname(dirname(dirname(__FILE__))); |
|
| 28 | - $appDir = basename(dirname(dirname(__FILE__))); |
|
| 29 | - $install = $root . DS . 'lib'; |
|
| 30 | - $composerInstall = $root . DS . $appDir . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; |
|
| 27 | + $root = dirname(dirname(dirname(__FILE__))); |
|
| 28 | + $appDir = basename(dirname(dirname(__FILE__))); |
|
| 29 | + $install = $root . DS . 'lib'; |
|
| 30 | + $composerInstall = $root . DS . $appDir . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib'; |
|
| 31 | 31 | |
| 32 | - // the following lines differ from its sibling |
|
| 33 | - // /lib/Cake/Console/Templates/skel/Console/cake.php |
|
| 34 | - if (file_exists($composerInstall . DS . $dispatcher)) { |
|
| 35 | - $install = $composerInstall; |
|
| 36 | - } |
|
| 32 | + // the following lines differ from its sibling |
|
| 33 | + // /lib/Cake/Console/Templates/skel/Console/cake.php |
|
| 34 | + if (file_exists($composerInstall . DS . $dispatcher)) { |
|
| 35 | + $install = $composerInstall; |
|
| 36 | + } |
|
| 37 | 37 | |
| 38 | - ini_set('include_path', $install . PATH_SEPARATOR . ini_get('include_path')); |
|
| 39 | - unset($root, $appDir, $install, $composerInstall); |
|
| 38 | + ini_set('include_path', $install . PATH_SEPARATOR . ini_get('include_path')); |
|
| 39 | + unset($root, $appDir, $install, $composerInstall); |
|
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | if (!include $dispatcher) { |
| 43 | - trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); |
|
| 43 | + trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); |
|
| 44 | 44 | } |
| 45 | 45 | unset($dispatcher); |
| 46 | 46 | |
@@ -1,112 +1,112 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | - App::uses('AppSettingModel', 'Lib/Model'); |
|
| 4 | - |
|
| 5 | - class Setting extends AppSettingModel { |
|
| 6 | - |
|
| 7 | - public $name = 'Setting'; |
|
| 8 | - |
|
| 9 | - public $primaryKey = 'name'; |
|
| 10 | - |
|
| 11 | - public $validate = [ |
|
| 12 | - 'name' => [ |
|
| 13 | - 'rule' => ['between', 1, 255], |
|
| 14 | - 'allowEmpty' => false |
|
| 15 | - ], |
|
| 16 | - 'value' => [ |
|
| 17 | - 'rule' => ['between', 0, 255], |
|
| 18 | - 'allowEmpty' => true |
|
| 19 | - ] |
|
| 20 | - ]; |
|
| 21 | - |
|
| 22 | - protected $_optionalEmailFields = [ |
|
| 23 | - 'email_contact', 'email_register', 'email_system' |
|
| 24 | - ]; |
|
| 25 | - |
|
| 26 | - /* @td getSettings vs Load why to functions? */ |
|
| 27 | - |
|
| 28 | - /** |
|
| 29 | - * Reads settings from DB and returns them in a compact array |
|
| 30 | - * |
|
| 31 | - * Note that this is the stored config in the DB. It may differ from the |
|
| 32 | - * current config used by the app in Config::read('Saito.Settings'), e.g. |
|
| 33 | - * when modified with a load-preset. |
|
| 34 | - * |
|
| 35 | - * @throws UnexpectedValueException |
|
| 36 | - * @return array Settings |
|
| 37 | - */ |
|
| 38 | - public function getSettings() { |
|
| 39 | - $settings = $this->find('all'); |
|
| 40 | - if (empty($settings)) { |
|
| 41 | - throw new UnexpectedValueException('No settings found in settings table.'); |
|
| 42 | - } |
|
| 43 | - $settings = $this->_compactKeyValue($settings); |
|
| 44 | - |
|
| 45 | - // edit_delay is normed to seconds |
|
| 46 | - $this->_normToSeconds($settings, 'edit_delay'); |
|
| 47 | - $this->_fillOptionalEmailAddresses($settings); |
|
| 48 | - |
|
| 49 | - return $settings; |
|
| 50 | - } |
|
| 51 | - |
|
| 52 | - /** |
|
| 53 | - * Loads settings from storage into Configuration `Saito.Settings` |
|
| 54 | - * |
|
| 55 | - * @param array $preset allows to overwrite loaded values |
|
| 56 | - * @return array Settings |
|
| 57 | - */ |
|
| 58 | - public function load($preset = []) { |
|
| 59 | - Stopwatch::start('Settings->getSettings()'); |
|
| 60 | - |
|
| 61 | - $settings = Cache::read('Saito.appSettings'); |
|
| 62 | - if (empty($settings)) { |
|
| 63 | - $settings = $this->getSettings(); |
|
| 64 | - Cache::write('Saito.appSettings', $settings); |
|
| 65 | - } |
|
| 66 | - if ($preset) { |
|
| 67 | - $settings = $preset + $settings; |
|
| 68 | - } |
|
| 69 | - Configure::write('Saito.Settings', $settings); |
|
| 70 | - |
|
| 71 | - Stopwatch::end('Settings->getSettings()'); |
|
| 72 | - } |
|
| 73 | - |
|
| 74 | - public function clearCache() { |
|
| 75 | - parent::clearCache(); |
|
| 76 | - Cache::delete('Saito.appSettings'); |
|
| 77 | - } |
|
| 78 | - |
|
| 79 | - /** |
|
| 80 | - * Returns a key-value array |
|
| 81 | - * |
|
| 82 | - * Fast version of Set::combine($results, '{n}.Setting.name', '{n}.Setting.value'); |
|
| 83 | - * |
|
| 84 | - * @param array $results |
|
| 85 | - * @return array |
|
| 86 | - */ |
|
| 87 | - protected function _compactKeyValue($results) { |
|
| 88 | - $settings = array(); |
|
| 89 | - foreach ($results as $result) { |
|
| 90 | - $settings[$result[$this->alias]['name']] = $result[$this->alias]['value']; |
|
| 91 | - } |
|
| 92 | - return $settings; |
|
| 93 | - } |
|
| 94 | - |
|
| 95 | - protected function _normToSeconds(&$settings, $field) { |
|
| 96 | - $settings[$field] = (int)$settings[$field] * 60; |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - /** |
|
| 100 | - * Defaults optional email addresses to main address |
|
| 101 | - * |
|
| 102 | - * @param $settings |
|
| 103 | - */ |
|
| 104 | - protected function _fillOptionalEmailAddresses(&$settings) { |
|
| 105 | - foreach ($this->_optionalEmailFields as $field) { |
|
| 106 | - if (empty($settings[$field])) { |
|
| 107 | - $settings[$field] = $settings['forum_email']; |
|
| 108 | - } |
|
| 109 | - } |
|
| 110 | - } |
|
| 111 | - |
|
| 112 | - } |
|
| 113 | 3 | \ No newline at end of file |
| 4 | + App::uses('AppSettingModel', 'Lib/Model'); |
|
| 5 | + |
|
| 6 | + class Setting extends AppSettingModel { |
|
| 7 | + |
|
| 8 | + public $name = 'Setting'; |
|
| 9 | + |
|
| 10 | + public $primaryKey = 'name'; |
|
| 11 | + |
|
| 12 | + public $validate = [ |
|
| 13 | + 'name' => [ |
|
| 14 | + 'rule' => ['between', 1, 255], |
|
| 15 | + 'allowEmpty' => false |
|
| 16 | + ], |
|
| 17 | + 'value' => [ |
|
| 18 | + 'rule' => ['between', 0, 255], |
|
| 19 | + 'allowEmpty' => true |
|
| 20 | + ] |
|
| 21 | + ]; |
|
| 22 | + |
|
| 23 | + protected $_optionalEmailFields = [ |
|
| 24 | + 'email_contact', 'email_register', 'email_system' |
|
| 25 | + ]; |
|
| 26 | + |
|
| 27 | + /* @td getSettings vs Load why to functions? */ |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * Reads settings from DB and returns them in a compact array |
|
| 31 | + * |
|
| 32 | + * Note that this is the stored config in the DB. It may differ from the |
|
| 33 | + * current config used by the app in Config::read('Saito.Settings'), e.g. |
|
| 34 | + * when modified with a load-preset. |
|
| 35 | + * |
|
| 36 | + * @throws UnexpectedValueException |
|
| 37 | + * @return array Settings |
|
| 38 | + */ |
|
| 39 | + public function getSettings() { |
|
| 40 | + $settings = $this->find('all'); |
|
| 41 | + if (empty($settings)) { |
|
| 42 | + throw new UnexpectedValueException('No settings found in settings table.'); |
|
| 43 | + } |
|
| 44 | + $settings = $this->_compactKeyValue($settings); |
|
| 45 | + |
|
| 46 | + // edit_delay is normed to seconds |
|
| 47 | + $this->_normToSeconds($settings, 'edit_delay'); |
|
| 48 | + $this->_fillOptionalEmailAddresses($settings); |
|
| 49 | + |
|
| 50 | + return $settings; |
|
| 51 | + } |
|
| 52 | + |
|
| 53 | + /** |
|
| 54 | + * Loads settings from storage into Configuration `Saito.Settings` |
|
| 55 | + * |
|
| 56 | + * @param array $preset allows to overwrite loaded values |
|
| 57 | + * @return array Settings |
|
| 58 | + */ |
|
| 59 | + public function load($preset = []) { |
|
| 60 | + Stopwatch::start('Settings->getSettings()'); |
|
| 61 | + |
|
| 62 | + $settings = Cache::read('Saito.appSettings'); |
|
| 63 | + if (empty($settings)) { |
|
| 64 | + $settings = $this->getSettings(); |
|
| 65 | + Cache::write('Saito.appSettings', $settings); |
|
| 66 | + } |
|
| 67 | + if ($preset) { |
|
| 68 | + $settings = $preset + $settings; |
|
| 69 | + } |
|
| 70 | + Configure::write('Saito.Settings', $settings); |
|
| 71 | + |
|
| 72 | + Stopwatch::end('Settings->getSettings()'); |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + public function clearCache() { |
|
| 76 | + parent::clearCache(); |
|
| 77 | + Cache::delete('Saito.appSettings'); |
|
| 78 | + } |
|
| 79 | + |
|
| 80 | + /** |
|
| 81 | + * Returns a key-value array |
|
| 82 | + * |
|
| 83 | + * Fast version of Set::combine($results, '{n}.Setting.name', '{n}.Setting.value'); |
|
| 84 | + * |
|
| 85 | + * @param array $results |
|
| 86 | + * @return array |
|
| 87 | + */ |
|
| 88 | + protected function _compactKeyValue($results) { |
|
| 89 | + $settings = array(); |
|
| 90 | + foreach ($results as $result) { |
|
| 91 | + $settings[$result[$this->alias]['name']] = $result[$this->alias]['value']; |
|
| 92 | + } |
|
| 93 | + return $settings; |
|
| 94 | + } |
|
| 95 | + |
|
| 96 | + protected function _normToSeconds(&$settings, $field) { |
|
| 97 | + $settings[$field] = (int)$settings[$field] * 60; |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + /** |
|
| 101 | + * Defaults optional email addresses to main address |
|
| 102 | + * |
|
| 103 | + * @param $settings |
|
| 104 | + */ |
|
| 105 | + protected function _fillOptionalEmailAddresses(&$settings) { |
|
| 106 | + foreach ($this->_optionalEmailFields as $field) { |
|
| 107 | + if (empty($settings[$field])) { |
|
| 108 | + $settings[$field] = $settings['forum_email']; |
|
| 109 | + } |
|
| 110 | + } |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + } |
|
| 114 | 114 | \ No newline at end of file |
@@ -1,145 +1,145 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | - App::uses('AppModel', 'Model'); |
|
| 4 | - |
|
| 5 | - /** |
|
| 6 | - * UserRead Model |
|
| 7 | - * |
|
| 8 | - * @property User $User |
|
| 9 | - */ |
|
| 10 | - class UserRead extends AppModel { |
|
| 11 | - |
|
| 12 | - /** |
|
| 13 | - * Caches user entries over multiple validations |
|
| 14 | - * |
|
| 15 | - * Esp. when many rows are set via Mix-view request |
|
| 16 | - * |
|
| 17 | - * @var array |
|
| 18 | - */ |
|
| 19 | - protected $_userCache = null; |
|
| 20 | - |
|
| 21 | - public $actsAs = ['Containable']; |
|
| 22 | - |
|
| 23 | - /** |
|
| 24 | - * belongsTo associations |
|
| 25 | - * |
|
| 26 | - * @var array |
|
| 27 | - */ |
|
| 28 | - public $belongsTo = [ |
|
| 29 | - 'User' => [ |
|
| 30 | - 'className' => 'User', |
|
| 31 | - 'foreignKey' => 'user_id', |
|
| 32 | - 'conditions' => '', |
|
| 33 | - 'fields' => '', |
|
| 34 | - 'order' => '' |
|
| 35 | - ] |
|
| 36 | - ]; |
|
| 37 | - |
|
| 38 | - /** |
|
| 39 | - * sets $entriesIds as read for user $userId |
|
| 40 | - * |
|
| 41 | - * @param array $entriesId [3, 4, 34] |
|
| 42 | - * @param int $userId |
|
| 43 | - */ |
|
| 44 | - public function setEntriesForUser($entriesId, $userId) { |
|
| 45 | - // filter out duplicates |
|
| 46 | - $userEntries = $this->getUser($userId); |
|
| 47 | - $entriesToSave = array_diff($entriesId, $userEntries); |
|
| 48 | - |
|
| 49 | - if (empty($entriesToSave)) { |
|
| 50 | - return; |
|
| 51 | - } |
|
| 52 | - |
|
| 53 | - $data = []; |
|
| 54 | - foreach ($entriesToSave as $entryId) { |
|
| 55 | - $this->_userCache[$userId][$entryId] = $entryId; |
|
| 56 | - $data[] = [ |
|
| 57 | - 'entry_id' => $entryId, |
|
| 58 | - 'user_id' => $userId |
|
| 59 | - ]; |
|
| 60 | - } |
|
| 61 | - $this->create(); |
|
| 62 | - $this->saveMany($data); |
|
| 63 | - } |
|
| 64 | - |
|
| 65 | - /** |
|
| 66 | - * gets all read postings of user with id $userId |
|
| 67 | - * |
|
| 68 | - * @param int $userId |
|
| 69 | - * @return array [1 => 1, 3 => 3] |
|
| 70 | - */ |
|
| 71 | - public function getUser($userId) { |
|
| 72 | - if (isset($this->_userCache[$userId])) { |
|
| 73 | - return $this->_userCache[$userId]; |
|
| 74 | - } |
|
| 75 | - |
|
| 76 | - Stopwatch::start('UserRead::getUser()'); |
|
| 77 | - $readPostings = $this->find('all', |
|
| 78 | - [ |
|
| 79 | - 'conditions' => ['user_id' => $userId], |
|
| 80 | - 'order' => $this->alias . '.entry_id', |
|
| 81 | - 'contain' => false |
|
| 82 | - ]); |
|
| 83 | - |
|
| 84 | - $read = []; |
|
| 85 | - foreach ($readPostings as $posting) { |
|
| 86 | - $id = (int)$posting[$this->alias]['entry_id']; |
|
| 87 | - $read[$id] = $id; |
|
| 88 | - } |
|
| 89 | - $this->_userCache[$userId] = $read; |
|
| 90 | - Stopwatch::stop('UserRead::getUser()'); |
|
| 91 | - |
|
| 92 | - return $this->_userCache[$userId]; |
|
| 93 | - } |
|
| 94 | - |
|
| 95 | - /** |
|
| 96 | - * deletes entries with lower entry-ID than $entryId |
|
| 97 | - * |
|
| 98 | - * @param $entryId |
|
| 99 | - * @throws InvalidArgumentException |
|
| 100 | - */ |
|
| 101 | - public function deleteEntriesBefore($entryId) { |
|
| 102 | - if (empty($entryId)) { |
|
| 103 | - throw new InvalidArgumentException; |
|
| 104 | - } |
|
| 105 | - $this->_userCache = null; |
|
| 106 | - $this->deleteAll([$this->alias . '.entry_id <' => $entryId], |
|
| 107 | - false, |
|
| 108 | - false); |
|
| 109 | - } |
|
| 110 | - |
|
| 111 | - /** |
|
| 112 | - * deletes entries with lower entry-ID than $entryId from user $userId |
|
| 113 | - * |
|
| 114 | - * @param $userId |
|
| 115 | - * @param $entryId |
|
| 116 | - * @throws InvalidArgumentException |
|
| 117 | - */ |
|
| 118 | - public function deleteUserEntriesBefore($userId, $entryId) { |
|
| 119 | - if (empty($userId) || empty($entryId)) { |
|
| 120 | - throw new InvalidArgumentException; |
|
| 121 | - } |
|
| 122 | - $this->_userCache = null; |
|
| 123 | - $this->deleteAll([ |
|
| 124 | - $this->alias . '.entry_id <' => $entryId, |
|
| 125 | - $this->alias . '.user_id' => $userId |
|
| 126 | - ], |
|
| 127 | - false, |
|
| 128 | - false); |
|
| 129 | - } |
|
| 130 | - |
|
| 131 | - /** |
|
| 132 | - * deletes entries from user $userId |
|
| 133 | - * |
|
| 134 | - * @param $userId |
|
| 135 | - * @throws InvalidArgumentException |
|
| 136 | - */ |
|
| 137 | - public function deleteAllFromUser($userId) { |
|
| 138 | - if (empty($userId)) { |
|
| 139 | - throw new InvalidArgumentException; |
|
| 140 | - } |
|
| 141 | - $this->_userCache = null; |
|
| 142 | - $this->deleteAll(['user_id' => $userId], false, false); |
|
| 143 | - } |
|
| 144 | - |
|
| 145 | - } |
|
| 3 | + App::uses('AppModel', 'Model'); |
|
| 4 | + |
|
| 5 | + /** |
|
| 6 | + * UserRead Model |
|
| 7 | + * |
|
| 8 | + * @property User $User |
|
| 9 | + */ |
|
| 10 | + class UserRead extends AppModel { |
|
| 11 | + |
|
| 12 | + /** |
|
| 13 | + * Caches user entries over multiple validations |
|
| 14 | + * |
|
| 15 | + * Esp. when many rows are set via Mix-view request |
|
| 16 | + * |
|
| 17 | + * @var array |
|
| 18 | + */ |
|
| 19 | + protected $_userCache = null; |
|
| 20 | + |
|
| 21 | + public $actsAs = ['Containable']; |
|
| 22 | + |
|
| 23 | + /** |
|
| 24 | + * belongsTo associations |
|
| 25 | + * |
|
| 26 | + * @var array |
|
| 27 | + */ |
|
| 28 | + public $belongsTo = [ |
|
| 29 | + 'User' => [ |
|
| 30 | + 'className' => 'User', |
|
| 31 | + 'foreignKey' => 'user_id', |
|
| 32 | + 'conditions' => '', |
|
| 33 | + 'fields' => '', |
|
| 34 | + 'order' => '' |
|
| 35 | + ] |
|
| 36 | + ]; |
|
| 37 | + |
|
| 38 | + /** |
|
| 39 | + * sets $entriesIds as read for user $userId |
|
| 40 | + * |
|
| 41 | + * @param array $entriesId [3, 4, 34] |
|
| 42 | + * @param int $userId |
|
| 43 | + */ |
|
| 44 | + public function setEntriesForUser($entriesId, $userId) { |
|
| 45 | + // filter out duplicates |
|
| 46 | + $userEntries = $this->getUser($userId); |
|
| 47 | + $entriesToSave = array_diff($entriesId, $userEntries); |
|
| 48 | + |
|
| 49 | + if (empty($entriesToSave)) { |
|
| 50 | + return; |
|
| 51 | + } |
|
| 52 | + |
|
| 53 | + $data = []; |
|
| 54 | + foreach ($entriesToSave as $entryId) { |
|
| 55 | + $this->_userCache[$userId][$entryId] = $entryId; |
|
| 56 | + $data[] = [ |
|
| 57 | + 'entry_id' => $entryId, |
|
| 58 | + 'user_id' => $userId |
|
| 59 | + ]; |
|
| 60 | + } |
|
| 61 | + $this->create(); |
|
| 62 | + $this->saveMany($data); |
|
| 63 | + } |
|
| 64 | + |
|
| 65 | + /** |
|
| 66 | + * gets all read postings of user with id $userId |
|
| 67 | + * |
|
| 68 | + * @param int $userId |
|
| 69 | + * @return array [1 => 1, 3 => 3] |
|
| 70 | + */ |
|
| 71 | + public function getUser($userId) { |
|
| 72 | + if (isset($this->_userCache[$userId])) { |
|
| 73 | + return $this->_userCache[$userId]; |
|
| 74 | + } |
|
| 75 | + |
|
| 76 | + Stopwatch::start('UserRead::getUser()'); |
|
| 77 | + $readPostings = $this->find('all', |
|
| 78 | + [ |
|
| 79 | + 'conditions' => ['user_id' => $userId], |
|
| 80 | + 'order' => $this->alias . '.entry_id', |
|
| 81 | + 'contain' => false |
|
| 82 | + ]); |
|
| 83 | + |
|
| 84 | + $read = []; |
|
| 85 | + foreach ($readPostings as $posting) { |
|
| 86 | + $id = (int)$posting[$this->alias]['entry_id']; |
|
| 87 | + $read[$id] = $id; |
|
| 88 | + } |
|
| 89 | + $this->_userCache[$userId] = $read; |
|
| 90 | + Stopwatch::stop('UserRead::getUser()'); |
|
| 91 | + |
|
| 92 | + return $this->_userCache[$userId]; |
|
| 93 | + } |
|
| 94 | + |
|
| 95 | + /** |
|
| 96 | + * deletes entries with lower entry-ID than $entryId |
|
| 97 | + * |
|
| 98 | + * @param $entryId |
|
| 99 | + * @throws InvalidArgumentException |
|
| 100 | + */ |
|
| 101 | + public function deleteEntriesBefore($entryId) { |
|
| 102 | + if (empty($entryId)) { |
|
| 103 | + throw new InvalidArgumentException; |
|
| 104 | + } |
|
| 105 | + $this->_userCache = null; |
|
| 106 | + $this->deleteAll([$this->alias . '.entry_id <' => $entryId], |
|
| 107 | + false, |
|
| 108 | + false); |
|
| 109 | + } |
|
| 110 | + |
|
| 111 | + /** |
|
| 112 | + * deletes entries with lower entry-ID than $entryId from user $userId |
|
| 113 | + * |
|
| 114 | + * @param $userId |
|
| 115 | + * @param $entryId |
|
| 116 | + * @throws InvalidArgumentException |
|
| 117 | + */ |
|
| 118 | + public function deleteUserEntriesBefore($userId, $entryId) { |
|
| 119 | + if (empty($userId) || empty($entryId)) { |
|
| 120 | + throw new InvalidArgumentException; |
|
| 121 | + } |
|
| 122 | + $this->_userCache = null; |
|
| 123 | + $this->deleteAll([ |
|
| 124 | + $this->alias . '.entry_id <' => $entryId, |
|
| 125 | + $this->alias . '.user_id' => $userId |
|
| 126 | + ], |
|
| 127 | + false, |
|
| 128 | + false); |
|
| 129 | + } |
|
| 130 | + |
|
| 131 | + /** |
|
| 132 | + * deletes entries from user $userId |
|
| 133 | + * |
|
| 134 | + * @param $userId |
|
| 135 | + * @throws InvalidArgumentException |
|
| 136 | + */ |
|
| 137 | + public function deleteAllFromUser($userId) { |
|
| 138 | + if (empty($userId)) { |
|
| 139 | + throw new InvalidArgumentException; |
|
| 140 | + } |
|
| 141 | + $this->_userCache = null; |
|
| 142 | + $this->deleteAll(['user_id' => $userId], false, false); |
|
| 143 | + } |
|
| 144 | + |
|
| 145 | + } |
|
@@ -1,18 +1,18 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | - App::uses('AppSettingModel', 'Lib/Model'); |
|
| 3 | + App::uses('AppSettingModel', 'Lib/Model'); |
|
| 4 | 4 | |
| 5 | - class SmileyCode extends AppSettingModel { |
|
| 5 | + class SmileyCode extends AppSettingModel { |
|
| 6 | 6 | |
| 7 | - public $name = 'SmileyCode'; |
|
| 7 | + public $name = 'SmileyCode'; |
|
| 8 | 8 | |
| 9 | - public $displayField = 'code'; |
|
| 9 | + public $displayField = 'code'; |
|
| 10 | 10 | |
| 11 | - public $belongsTo = [ |
|
| 12 | - 'Smiley' => [ |
|
| 13 | - 'className' => 'Smiley', |
|
| 14 | - 'foreignKey' => 'smiley_id' |
|
| 15 | - ] |
|
| 16 | - ]; |
|
| 11 | + public $belongsTo = [ |
|
| 12 | + 'Smiley' => [ |
|
| 13 | + 'className' => 'Smiley', |
|
| 14 | + 'foreignKey' => 'smiley_id' |
|
| 15 | + ] |
|
| 16 | + ]; |
|
| 17 | 17 | |
| 18 | - } |
|
| 18 | + } |
|