Completed
Push — master ( e5db64...945d9a )
by Schlaefer
05:09 queued 28s
created
app/Console/Command/DummyDataShell.php 1 patch
Indentation   +168 added lines, -168 removed lines patch added patch discarded remove patch
@@ -1,171 +1,171 @@
 block discarded – undo
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
 
Please login to merge, or discard this patch.
app/Console/Command/SiegeShell.php 1 patch
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -1,87 +1,87 @@
 block discarded – undo
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
 
Please login to merge, or discard this patch.
app/Console/cake.php 1 patch
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -18,29 +18,29 @@
 block discarded – undo
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
 
Please login to merge, or discard this patch.
app/Model/Setting.php 1 patch
Indentation   +110 added lines, -110 removed lines patch added patch discarded remove patch
@@ -1,112 +1,112 @@
 block discarded – undo
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
Please login to merge, or discard this patch.
app/Model/UserRead.php 1 patch
Indentation   +143 added lines, -143 removed lines patch added patch discarded remove patch
@@ -1,145 +1,145 @@
 block discarded – undo
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
+    }
Please login to merge, or discard this patch.
app/Model/SmileyCode.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -1,18 +1,18 @@
 block discarded – undo
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
+    }
Please login to merge, or discard this patch.
app/Model/Entry.php 1 patch
Indentation   +935 added lines, -935 removed lines patch added patch discarded remove patch
@@ -1,8 +1,8 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-	use Saito\User\ForumsUserInterface;
3
+    use Saito\User\ForumsUserInterface;
4 4
 
5
-	App::uses('AppModel', 'Model');
5
+    App::uses('AppModel', 'Model');
6 6
 
7 7
 /**
8 8
  *
@@ -23,225 +23,225 @@  discard block
 block discarded – undo
23 23
  * @td After mlf is gone `edited_by` should conatin a User.id, not the username string.
24 24
  *
25 25
  */
26
-	class Entry extends AppModel {
27
-
28
-		public $name = 'Entry';
29
-
30
-		public $primaryKey = 'id';
31
-
32
-		public $actsAs = [
33
-			'Markup',
34
-			'Containable',
35
-			'Search.Searchable',
36
-			'Tree'
37
-		];
38
-
39
-		public $findMethods = array(
40
-			'feed' => true,
41
-			'entry' => true
42
-		);
43
-
44
-		/**
45
-		 * Fields for search plugin
46
-		 *
47
-		 * @var array
48
-		 */
49
-		public $filterArgs = [
50
-				'subject' => ['type' => 'like'],
51
-				'text' => ['type' => 'like'],
52
-				'name' => ['type' => 'like'],
53
-				'category_id' => ['type' => 'value'],
54
-		];
55
-
56
-		public $belongsTo = array(
57
-			'Category' => array(
58
-				'className' => 'Category',
59
-				'foreignKey' => 'category_id',
60
-			),
61
-			'User' => array(
62
-				'className' => 'User',
63
-				'foreignKey' => 'user_id',
64
-				'counterCache' => true,
65
-			),
66
-		);
67
-
68
-		public $hasMany = array(
69
-			'Bookmark' => array(
70
-				'foreignKey' => 'entry_id',
71
-				'dependent' => true,
72
-			),
73
-			'Esevent' => array(
74
-				'foreignKey' => 'subject',
75
-				'conditions' => array('Esevent.subject' => 'Entry.id'),
76
-			),
77
-			'UserRead' => [
78
-				'foreignKey' => 'entry_id',
79
-				'dependent' => true
80
-			]
81
-		);
82
-
83
-		public $validate = [
84
-				'subject' => [
85
-						'notEmpty' => ['rule' => 'notBlank'],
86
-						'maxLength' => ['rule' => 'validateSubjectMaxLength']
87
-				],
88
-				'category_id' => [
89
-						'notEmpty' => ['rule' => 'notBlank'],
90
-						'numeric' => ['rule' => 'numeric'],
91
-						'isAllowed' => ['rule' => 'validateCategoryIsAllowed']
92
-				],
93
-				'user_id' => ['rule' => 'numeric'],
94
-				'views' => ['rule' => ['comparison', '>=', 0]],
95
-			// used in full text search
96
-				'name' => array()
97
-		];
98
-
99
-		/**
100
-		 * Fields allowed in public output
101
-		 *
102
-		 * @var array
103
-		 */
104
-		protected $_allowedPublicOutputFields = [
105
-			'Entry.id',
106
-			'Entry.pid',
107
-			'Entry.tid',
108
-			'Entry.time',
109
-			'Entry.last_answer',
110
-			'Entry.edited',
111
-			'Entry.edited_by',
112
-			'Entry.user_id',
113
-			'Entry.name',
114
-			'Entry.subject',
115
-			'Entry.category_id',
116
-			'Entry.text',
117
-			'Entry.locked',
118
-			'Entry.fixed',
119
-			'Entry.views',
120
-			'User.username'
121
-		];
122
-
123
-		/**
124
-		 * field list necessary for displaying a thread_line
125
-		 *
126
-		 * Entry.text determine if Entry is n/t
127
-		 *
128
-		 * @var string
129
-		 */
130
-		public $threadLineFieldList = [
131
-			'Entry.id',
132
-			'Entry.pid',
133
-			'Entry.tid',
134
-			'Entry.subject',
135
-			'Entry.text',
136
-			'Entry.time',
137
-			'Entry.fixed',
138
-			'Entry.last_answer',
139
-			'Entry.views',
140
-			'Entry.user_id',
141
-			'Entry.locked',
142
-			'Entry.name',
143
-			'Entry.solves',
144
-
145
-			'User.username',
146
-
147
-			'Category.accession',
148
-			'Category.category',
149
-			'Category.description'
150
-		];
151
-
152
-		/**
153
-		 * fields additional to $threadLineFieldList to show complete entry
154
-		 *
155
-		 * @var string
156
-		 */
157
-		public $showEntryFieldListAdditional = [
158
-			'Entry.edited',
159
-			'Entry.edited_by',
160
-			'Entry.ip',
161
-			'Entry.category_id',
162
-
163
-			'User.id',
164
-			'User.signature',
165
-			'User.user_place'
166
-		];
167
-
168
-		/**
169
-		 * Allowed external user input
170
-		 *
171
-		 * @var array
172
-		 */
173
-		public $allowedInputFields = [
174
-			'create' => [
175
-				'category_id',
176
-				'pid',
177
-				'subject',
178
-				'text'
179
-			],
180
-			'update' => [
181
-				'id',
182
-				'category_id',
183
-				'subject',
184
-				'text'
185
-			]
186
-		];
187
-
188
-		protected $_settings = [
189
-			'edit_period' => 20,
190
-			'subject_maxlength' => 100
191
-		];
26
+    class Entry extends AppModel {
27
+
28
+        public $name = 'Entry';
29
+
30
+        public $primaryKey = 'id';
31
+
32
+        public $actsAs = [
33
+            'Markup',
34
+            'Containable',
35
+            'Search.Searchable',
36
+            'Tree'
37
+        ];
38
+
39
+        public $findMethods = array(
40
+            'feed' => true,
41
+            'entry' => true
42
+        );
43
+
44
+        /**
45
+         * Fields for search plugin
46
+         *
47
+         * @var array
48
+         */
49
+        public $filterArgs = [
50
+                'subject' => ['type' => 'like'],
51
+                'text' => ['type' => 'like'],
52
+                'name' => ['type' => 'like'],
53
+                'category_id' => ['type' => 'value'],
54
+        ];
55
+
56
+        public $belongsTo = array(
57
+            'Category' => array(
58
+                'className' => 'Category',
59
+                'foreignKey' => 'category_id',
60
+            ),
61
+            'User' => array(
62
+                'className' => 'User',
63
+                'foreignKey' => 'user_id',
64
+                'counterCache' => true,
65
+            ),
66
+        );
67
+
68
+        public $hasMany = array(
69
+            'Bookmark' => array(
70
+                'foreignKey' => 'entry_id',
71
+                'dependent' => true,
72
+            ),
73
+            'Esevent' => array(
74
+                'foreignKey' => 'subject',
75
+                'conditions' => array('Esevent.subject' => 'Entry.id'),
76
+            ),
77
+            'UserRead' => [
78
+                'foreignKey' => 'entry_id',
79
+                'dependent' => true
80
+            ]
81
+        );
82
+
83
+        public $validate = [
84
+                'subject' => [
85
+                        'notEmpty' => ['rule' => 'notBlank'],
86
+                        'maxLength' => ['rule' => 'validateSubjectMaxLength']
87
+                ],
88
+                'category_id' => [
89
+                        'notEmpty' => ['rule' => 'notBlank'],
90
+                        'numeric' => ['rule' => 'numeric'],
91
+                        'isAllowed' => ['rule' => 'validateCategoryIsAllowed']
92
+                ],
93
+                'user_id' => ['rule' => 'numeric'],
94
+                'views' => ['rule' => ['comparison', '>=', 0]],
95
+            // used in full text search
96
+                'name' => array()
97
+        ];
98
+
99
+        /**
100
+         * Fields allowed in public output
101
+         *
102
+         * @var array
103
+         */
104
+        protected $_allowedPublicOutputFields = [
105
+            'Entry.id',
106
+            'Entry.pid',
107
+            'Entry.tid',
108
+            'Entry.time',
109
+            'Entry.last_answer',
110
+            'Entry.edited',
111
+            'Entry.edited_by',
112
+            'Entry.user_id',
113
+            'Entry.name',
114
+            'Entry.subject',
115
+            'Entry.category_id',
116
+            'Entry.text',
117
+            'Entry.locked',
118
+            'Entry.fixed',
119
+            'Entry.views',
120
+            'User.username'
121
+        ];
122
+
123
+        /**
124
+         * field list necessary for displaying a thread_line
125
+         *
126
+         * Entry.text determine if Entry is n/t
127
+         *
128
+         * @var string
129
+         */
130
+        public $threadLineFieldList = [
131
+            'Entry.id',
132
+            'Entry.pid',
133
+            'Entry.tid',
134
+            'Entry.subject',
135
+            'Entry.text',
136
+            'Entry.time',
137
+            'Entry.fixed',
138
+            'Entry.last_answer',
139
+            'Entry.views',
140
+            'Entry.user_id',
141
+            'Entry.locked',
142
+            'Entry.name',
143
+            'Entry.solves',
144
+
145
+            'User.username',
146
+
147
+            'Category.accession',
148
+            'Category.category',
149
+            'Category.description'
150
+        ];
151
+
152
+        /**
153
+         * fields additional to $threadLineFieldList to show complete entry
154
+         *
155
+         * @var string
156
+         */
157
+        public $showEntryFieldListAdditional = [
158
+            'Entry.edited',
159
+            'Entry.edited_by',
160
+            'Entry.ip',
161
+            'Entry.category_id',
162
+
163
+            'User.id',
164
+            'User.signature',
165
+            'User.user_place'
166
+        ];
167
+
168
+        /**
169
+         * Allowed external user input
170
+         *
171
+         * @var array
172
+         */
173
+        public $allowedInputFields = [
174
+            'create' => [
175
+                'category_id',
176
+                'pid',
177
+                'subject',
178
+                'text'
179
+            ],
180
+            'update' => [
181
+                'id',
182
+                'category_id',
183
+                'subject',
184
+                'text'
185
+            ]
186
+        ];
187
+
188
+        protected $_settings = [
189
+            'edit_period' => 20,
190
+            'subject_maxlength' => 100
191
+        ];
192 192
 
193 193
 /**
194 194
  * Caching for isRoot()
195 195
  *
196 196
  * @var array
197 197
  */
198
-		protected $_isRoot = [];
199
-
200
-		/**
201
-		 * @param ForumsUserInterface $User
202
-		 * @param array $options
203
-		 * @return array|mixed
204
-		 */
205
-		public function getRecentEntries(CurrentUserComponent $User, array $options = []) {
206
-			Stopwatch::start('Model->User->getRecentEntries()');
207
-
208
-			$options += [
209
-				'user_id' => null,
210
-				'limit' => 10,
211
-				'category_id' => $User->Categories->getAllowed()
212
-			];
213
-
214
-			$_cacheKey = 'Entry.recentEntries-' . md5(serialize($options));
215
-			$_cachedEntry = Cache::read($_cacheKey, 'entries');
216
-			if ($_cachedEntry) {
217
-				Stopwatch::stop('Model->User->getRecentEntries()');
218
-				return $_cachedEntry;
219
-			}
220
-
221
-			$conditions = array();
222
-			if ($options['user_id'] !== null) {
223
-				$conditions[]['Entry.user_id'] = $options['user_id'];
224
-			}
225
-			if ($options['category_id'] !== null):
226
-				$conditions[]['Entry.category_id'] = $options['category_id'];
227
-			endif;
228
-
229
-			$result = $this->find(
230
-				'all',
231
-				[
232
-					'contain' => array('User', 'Category'),
233
-					'fields' => $this->threadLineFieldList,
234
-					'conditions' => $conditions,
235
-					'limit' => $options['limit'],
236
-					'order' => 'time DESC'
237
-				]
238
-			);
239
-
240
-			Cache::write($_cacheKey, $result, 'entries');
241
-
242
-			Stopwatch::stop('Model->User->getRecentEntries()');
243
-			return $result;
244
-		}
198
+        protected $_isRoot = [];
199
+
200
+        /**
201
+         * @param ForumsUserInterface $User
202
+         * @param array $options
203
+         * @return array|mixed
204
+         */
205
+        public function getRecentEntries(CurrentUserComponent $User, array $options = []) {
206
+            Stopwatch::start('Model->User->getRecentEntries()');
207
+
208
+            $options += [
209
+                'user_id' => null,
210
+                'limit' => 10,
211
+                'category_id' => $User->Categories->getAllowed()
212
+            ];
213
+
214
+            $_cacheKey = 'Entry.recentEntries-' . md5(serialize($options));
215
+            $_cachedEntry = Cache::read($_cacheKey, 'entries');
216
+            if ($_cachedEntry) {
217
+                Stopwatch::stop('Model->User->getRecentEntries()');
218
+                return $_cachedEntry;
219
+            }
220
+
221
+            $conditions = array();
222
+            if ($options['user_id'] !== null) {
223
+                $conditions[]['Entry.user_id'] = $options['user_id'];
224
+            }
225
+            if ($options['category_id'] !== null):
226
+                $conditions[]['Entry.category_id'] = $options['category_id'];
227
+            endif;
228
+
229
+            $result = $this->find(
230
+                'all',
231
+                [
232
+                    'contain' => array('User', 'Category'),
233
+                    'fields' => $this->threadLineFieldList,
234
+                    'conditions' => $conditions,
235
+                    'limit' => $options['limit'],
236
+                    'order' => 'time DESC'
237
+                ]
238
+            );
239
+
240
+            Cache::write($_cacheKey, $result, 'entries');
241
+
242
+            Stopwatch::stop('Model->User->getRecentEntries()');
243
+            return $result;
244
+        }
245 245
 
246 246
 /**
247 247
  * Finds the thread-id for a posting
@@ -250,233 +250,233 @@  discard block
 block discarded – undo
250 250
  * @return int Thread-Id
251 251
  * @throws UnexpectedValueException
252 252
  */
253
-		public function getThreadId($id) {
254
-			$entry = $this->find(
255
-				'first',
256
-				[
257
-					'contain' => false,
258
-					'conditions' => ['Entry.id' => $id],
259
-					'fields' => 'Entry.tid'
260
-
261
-				]
262
-			);
263
-			if ($entry == false) {
264
-				throw new UnexpectedValueException('Posting not found. Posting-Id: ' . $id);
265
-			}
266
-			return $entry['Entry']['tid'];
267
-		}
253
+        public function getThreadId($id) {
254
+            $entry = $this->find(
255
+                'first',
256
+                [
257
+                    'contain' => false,
258
+                    'conditions' => ['Entry.id' => $id],
259
+                    'fields' => 'Entry.tid'
260
+
261
+                ]
262
+            );
263
+            if ($entry == false) {
264
+                throw new UnexpectedValueException('Posting not found. Posting-Id: ' . $id);
265
+            }
266
+            return $entry['Entry']['tid'];
267
+        }
268 268
 
269 269
 /**
270 270
  * Shorthand for reading an entry with full data
271 271
  */
272
-		public function get($id) {
273
-			return $this->find('entry',
274
-					['conditions' => [$this->alias . '.id' => $id]]);
275
-		}
272
+        public function get($id) {
273
+            return $this->find('entry',
274
+                    ['conditions' => [$this->alias . '.id' => $id]]);
275
+        }
276 276
 
277 277
 /**
278 278
  * @param $id
279 279
  * @return mixed
280 280
  * @throws UnexpectedValueException
281 281
  */
282
-		public function getParentId($id) {
283
-			$entry = $this->find(
284
-				'first',
285
-				[
286
-					'contain' => false,
287
-					'conditions' => ['Entry.id' => $id],
288
-					'fields' => 'Entry.pid'
289
-
290
-				]
291
-			);
292
-			if ($entry == false) {
293
-				throw new UnexpectedValueException('Posting not found. Posting-Id: ' . $id);
294
-			}
295
-			return $entry['Entry']['pid'];
296
-		}
297
-
298
-		/**
299
-		 * creates a new root or child entry for a node
300
-		 *
301
-		 * fields in $data are filtered
302
-		 *
303
-		 * @param $data
304
-		 * @return array|bool|mixed
305
-		 */
306
-		public function createPosting($data) {
307
-			if (!isset($data[$this->alias]['pid'])) {
308
-				$data[$this->alias]['pid'] = 0;
309
-			}
310
-
311
-			if (isset($data[$this->alias]['subject']) === false) {
312
-				return false;
313
-			}
314
-
315
-			try {
316
-				$this->prepare($data, ['preFilterFields' => 'create']);
317
-			} catch (Exception $e) {
318
-				return false;
319
-			}
320
-
321
-			$data[$this->alias]['user_id'] = $this->CurrentUser->getId();
322
-			$data[$this->alias]['name'] = $this->CurrentUser['username'];
323
-
324
-			$data[$this->alias]['time'] = bDate();
325
-			$data[$this->alias]['last_answer'] = bDate();
326
-			$data[$this->alias]['ip'] = self::_getIp();
327
-
328
-			$this->create();
329
-			$_newPosting = $this->save($data);
330
-
331
-			if ($_newPosting === false) {
332
-				return false;
333
-			}
334
-
335
-			$_newPostingId = $this->id;
336
-
337
-			// make sure we pass the complete ['Entry'] dataset to events
338
-			$this->contain();
339
-			$_newPosting = $this->read();
340
-
341
-			if ($this->isRoot($data)) {
342
-				// thread-id of new thread is its own id
343
-				if ($this->save(['tid' => $_newPostingId], false, ['tid']) === false) {
344
-					// @td raise error and/or roll back new entry
345
-					return false;
346
-				} else {
347
-					$_newPosting[$this->alias]['tid'] = $_newPostingId;
348
-					$this->Category->id = $data[$this->alias]['category_id'];
349
-					$this->Category->updateThreadCounter();
350
-				}
351
-				$this->_dispatchEvent(
352
-					'Model.Thread.create',
353
-					[
354
-						'subject' => $_newPosting[$this->alias]['id'],
355
-						'data' => $_newPosting
356
-					]
357
-				);
358
-			} else {
359
-				// update last answer time of root entry
360
-				$this->clear();
361
-				$this->id = $_newPosting[$this->alias]['tid'];
362
-				$this->set('last_answer', $_newPosting[$this->alias]['last_answer']);
363
-				if ($this->save() === false) {
364
-					// @td raise error and/or roll back new entry
365
-					return false;
366
-				}
367
-
368
-				$this->_dispatchEvent(
369
-					'Model.Entry.replyToEntry',
370
-					[
371
-						'subject' => $_newPosting[$this->alias]['pid'],
372
-						'data' => $_newPosting
373
-					]
374
-				);
375
-				$this->_dispatchEvent(
376
-					'Model.Entry.replyToThread',
377
-					[
378
-						'subject' => $_newPosting[$this->alias]['tid'],
379
-						'data' => $_newPosting
380
-					]
381
-				);
382
-			}
383
-
384
-			$this->id = $_newPostingId;
385
-			$_newPosting[$this->alias]['subject'] = Sanitize::html($_newPosting[$this->alias]['subject']);
386
-			$_newPosting[$this->alias]['text'] = Sanitize::html($_newPosting[$this->alias]['text']);
387
-			return $_newPosting;
388
-		}
389
-
390
-		/**
391
-		 * Updates a posting
392
-		 *
393
-		 * fields in $data are filtered except for $id!
394
-		 *
395
-		 * @param $data
396
-		 * @param null $CurrentUser
397
-		 * @return array|mixed
398
-		 * @throws NotFoundException
399
-		 * @throws InvalidArgumentException
400
-		 */
401
-		public function update($data, $CurrentUser = null) {
402
-			if ($CurrentUser !== null) {
403
-				$this->CurrentUser = $CurrentUser;
404
-			}
405
-
406
-			if (empty($data[$this->alias]['id'])) {
407
-				throw new InvalidArgumentException('Missing entry id in arguments.');
408
-			}
409
-
410
-			$id = $data[$this->alias]['id'];
411
-			if (!$this->exists($id)) {
412
-				throw new NotFoundException(sprintf('Entry with id `%s` not found.', $id));
413
-			}
414
-
415
-			$this->prepare($data, ['preFilterFields' => 'update']);
416
-
417
-			// prevents normal user of changing category of complete thread when answering
418
-			// @todo this should be refactored together with the change category handling in beforeSave()
419
-			if ($this->isRoot($data) === false) {
420
-				unset($data[$this->alias]['category_id']);
421
-			}
422
-
423
-			$data[$this->alias]['edited'] = bDate();
424
-			$data[$this->alias]['edited_by'] = $this->CurrentUser['username'];
425
-
426
-			$this->validator()->add(
427
-				'edited_by',
428
-				'isEditingAllowed',
429
-				[
430
-					'rule' => 'validateEditingAllowed'
431
-				]
432
-			);
433
-
434
-			$result = $this->save($data);
435
-
436
-			if ($result) {
437
-				$this->contain();
438
-				$result = $this->read() + $data;
439
-				$this->_dispatchEvent(
440
-					'Model.Entry.update',
441
-					[
442
-						'subject' => $result[$this->alias]['id'],
443
-						'data' => $result
444
-					]
445
-				);
446
-			}
447
-
448
-			return $result;
449
-		}
450
-
451
-		/**
452
-		 * Update view counter on all entries in a thread
453
-		 *
454
-		 * Note that this function unbinds the model associations for performance.
455
-		 * Otherwise updateAll() left joins all associated models.
456
-		 *
457
-		 * @param $tid thread-ID
458
-		 * @param $uid entries with this user-id are not updated
459
-		 */
460
-		public function threadIncrementViews($tid, $uid = null) {
461
-			Stopwatch::start('Entry::threadIncrementViews');
462
-			$_where = ['Entry.tid' => $tid];
463
-			if ($uid && is_int($uid)) {
464
-				$_where['Entry.user_id !='] = $uid;
465
-			}
466
-			// $_belongsTo = $this->belongsTo;
467
-			$this->unbindModel(['belongsTo' => array_keys($this->belongsTo)]);
468
-			$this->updateAll(['Entry.views' => 'Entry.views + 1'], $_where);
469
-			// $this->bindModel(['belongsTo' => $_belongsTo]);
470
-			Stopwatch::stop('Entry::threadIncrementViews');
471
-		}
282
+        public function getParentId($id) {
283
+            $entry = $this->find(
284
+                'first',
285
+                [
286
+                    'contain' => false,
287
+                    'conditions' => ['Entry.id' => $id],
288
+                    'fields' => 'Entry.pid'
289
+
290
+                ]
291
+            );
292
+            if ($entry == false) {
293
+                throw new UnexpectedValueException('Posting not found. Posting-Id: ' . $id);
294
+            }
295
+            return $entry['Entry']['pid'];
296
+        }
297
+
298
+        /**
299
+         * creates a new root or child entry for a node
300
+         *
301
+         * fields in $data are filtered
302
+         *
303
+         * @param $data
304
+         * @return array|bool|mixed
305
+         */
306
+        public function createPosting($data) {
307
+            if (!isset($data[$this->alias]['pid'])) {
308
+                $data[$this->alias]['pid'] = 0;
309
+            }
310
+
311
+            if (isset($data[$this->alias]['subject']) === false) {
312
+                return false;
313
+            }
314
+
315
+            try {
316
+                $this->prepare($data, ['preFilterFields' => 'create']);
317
+            } catch (Exception $e) {
318
+                return false;
319
+            }
320
+
321
+            $data[$this->alias]['user_id'] = $this->CurrentUser->getId();
322
+            $data[$this->alias]['name'] = $this->CurrentUser['username'];
323
+
324
+            $data[$this->alias]['time'] = bDate();
325
+            $data[$this->alias]['last_answer'] = bDate();
326
+            $data[$this->alias]['ip'] = self::_getIp();
327
+
328
+            $this->create();
329
+            $_newPosting = $this->save($data);
330
+
331
+            if ($_newPosting === false) {
332
+                return false;
333
+            }
334
+
335
+            $_newPostingId = $this->id;
336
+
337
+            // make sure we pass the complete ['Entry'] dataset to events
338
+            $this->contain();
339
+            $_newPosting = $this->read();
340
+
341
+            if ($this->isRoot($data)) {
342
+                // thread-id of new thread is its own id
343
+                if ($this->save(['tid' => $_newPostingId], false, ['tid']) === false) {
344
+                    // @td raise error and/or roll back new entry
345
+                    return false;
346
+                } else {
347
+                    $_newPosting[$this->alias]['tid'] = $_newPostingId;
348
+                    $this->Category->id = $data[$this->alias]['category_id'];
349
+                    $this->Category->updateThreadCounter();
350
+                }
351
+                $this->_dispatchEvent(
352
+                    'Model.Thread.create',
353
+                    [
354
+                        'subject' => $_newPosting[$this->alias]['id'],
355
+                        'data' => $_newPosting
356
+                    ]
357
+                );
358
+            } else {
359
+                // update last answer time of root entry
360
+                $this->clear();
361
+                $this->id = $_newPosting[$this->alias]['tid'];
362
+                $this->set('last_answer', $_newPosting[$this->alias]['last_answer']);
363
+                if ($this->save() === false) {
364
+                    // @td raise error and/or roll back new entry
365
+                    return false;
366
+                }
367
+
368
+                $this->_dispatchEvent(
369
+                    'Model.Entry.replyToEntry',
370
+                    [
371
+                        'subject' => $_newPosting[$this->alias]['pid'],
372
+                        'data' => $_newPosting
373
+                    ]
374
+                );
375
+                $this->_dispatchEvent(
376
+                    'Model.Entry.replyToThread',
377
+                    [
378
+                        'subject' => $_newPosting[$this->alias]['tid'],
379
+                        'data' => $_newPosting
380
+                    ]
381
+                );
382
+            }
383
+
384
+            $this->id = $_newPostingId;
385
+            $_newPosting[$this->alias]['subject'] = Sanitize::html($_newPosting[$this->alias]['subject']);
386
+            $_newPosting[$this->alias]['text'] = Sanitize::html($_newPosting[$this->alias]['text']);
387
+            return $_newPosting;
388
+        }
389
+
390
+        /**
391
+         * Updates a posting
392
+         *
393
+         * fields in $data are filtered except for $id!
394
+         *
395
+         * @param $data
396
+         * @param null $CurrentUser
397
+         * @return array|mixed
398
+         * @throws NotFoundException
399
+         * @throws InvalidArgumentException
400
+         */
401
+        public function update($data, $CurrentUser = null) {
402
+            if ($CurrentUser !== null) {
403
+                $this->CurrentUser = $CurrentUser;
404
+            }
405
+
406
+            if (empty($data[$this->alias]['id'])) {
407
+                throw new InvalidArgumentException('Missing entry id in arguments.');
408
+            }
409
+
410
+            $id = $data[$this->alias]['id'];
411
+            if (!$this->exists($id)) {
412
+                throw new NotFoundException(sprintf('Entry with id `%s` not found.', $id));
413
+            }
414
+
415
+            $this->prepare($data, ['preFilterFields' => 'update']);
416
+
417
+            // prevents normal user of changing category of complete thread when answering
418
+            // @todo this should be refactored together with the change category handling in beforeSave()
419
+            if ($this->isRoot($data) === false) {
420
+                unset($data[$this->alias]['category_id']);
421
+            }
422
+
423
+            $data[$this->alias]['edited'] = bDate();
424
+            $data[$this->alias]['edited_by'] = $this->CurrentUser['username'];
425
+
426
+            $this->validator()->add(
427
+                'edited_by',
428
+                'isEditingAllowed',
429
+                [
430
+                    'rule' => 'validateEditingAllowed'
431
+                ]
432
+            );
433
+
434
+            $result = $this->save($data);
435
+
436
+            if ($result) {
437
+                $this->contain();
438
+                $result = $this->read() + $data;
439
+                $this->_dispatchEvent(
440
+                    'Model.Entry.update',
441
+                    [
442
+                        'subject' => $result[$this->alias]['id'],
443
+                        'data' => $result
444
+                    ]
445
+                );
446
+            }
447
+
448
+            return $result;
449
+        }
450
+
451
+        /**
452
+         * Update view counter on all entries in a thread
453
+         *
454
+         * Note that this function unbinds the model associations for performance.
455
+         * Otherwise updateAll() left joins all associated models.
456
+         *
457
+         * @param $tid thread-ID
458
+         * @param $uid entries with this user-id are not updated
459
+         */
460
+        public function threadIncrementViews($tid, $uid = null) {
461
+            Stopwatch::start('Entry::threadIncrementViews');
462
+            $_where = ['Entry.tid' => $tid];
463
+            if ($uid && is_int($uid)) {
464
+                $_where['Entry.user_id !='] = $uid;
465
+            }
466
+            // $_belongsTo = $this->belongsTo;
467
+            $this->unbindModel(['belongsTo' => array_keys($this->belongsTo)]);
468
+            $this->updateAll(['Entry.views' => 'Entry.views + 1'], $_where);
469
+            // $this->bindModel(['belongsTo' => $_belongsTo]);
470
+            Stopwatch::stop('Entry::threadIncrementViews');
471
+        }
472 472
 
473 473
 /**
474 474
  *
475 475
  * @mb `views` into extra related table if performance becomes a problem
476 476
  */
477
-		public function incrementViews($id, $amount = 1) {
478
-			$this->increment($id, 'views', $amount);
479
-		}
477
+        public function incrementViews($id, $amount = 1) {
478
+            $this->increment($id, 'views', $amount);
479
+        }
480 480
 
481 481
 /**
482 482
  * tree of a single node and its subentries
@@ -489,77 +489,77 @@  discard block
 block discarded – undo
489 489
  * @param array $options
490 490
  * @return array tree
491 491
  */
492
-		public function treeForNode($id, $options = array()) {
493
-			$options += [
494
-				'root' => false,
495
-				'complete' => false
496
-			];
497
-
498
-			if ($options['root']) {
499
-				$tid = $id;
500
-			} else {
501
-				$tid = $this->getThreadId($id);
502
-			}
503
-
504
-			$fields = null;
505
-			if ($options['complete']) {
506
-				$fields = array_merge($this->threadLineFieldList, $this->showEntryFieldListAdditional);
507
-			}
508
-
509
-			$tree = $this->treesForThreads([$tid], null, $fields);
510
-
511
-			if ((int)$tid !== (int)$id) {
512
-				$tree = $this->treeGetSubtree($tree, $id);
513
-			}
514
-
515
-			return $tree;
516
-		}
517
-
518
-		/**
519
-		 * trees for multiple tids
520
-		 *
521
-		 * @param $ids
522
-		 * @param null $order
523
-		 * @param null $fieldlist
524
-		 * @return array|bool false if no threads or array with Posting
525
-		 */
526
-		public function treesForThreads($ids, $order = null, $fieldlist = null) {
527
-			if (empty($ids)) {
528
-				return [];
529
-			}
530
-
531
-			Stopwatch::start('Model->Entries->treeForThreads() DB');
532
-
533
-			if (empty($order)) {
534
-				$order = 'last_answer ASC';
535
-			}
536
-
537
-			if ($fieldlist === null) {
538
-				$fieldlist = $this->threadLineFieldList;
539
-			}
540
-
541
-			$entries = $this->_getThreadEntries(
542
-				$ids,
543
-				['order' => $order, 'fields' => $fieldlist]
544
-			);
545
-
546
-			Stopwatch::stop('Model->Entries->treeForThreads() DB');
547
-			Stopwatch::start('Model->Entries->treeForThreads() CPU');
548
-
549
-			$threads = false;
550
-			if ($entries) {
551
-				$threads = [];
552
-				$entries = $this->treeBuild($entries);
553
-				foreach ($entries as $thread) {
554
-					$id = (int)$thread['Entry']['tid'];
555
-					$threads[$id] = $thread;
556
-				}
557
-			}
558
-
559
-			Stopwatch::stop('Model->Entries->treeForThreads() CPU');
560
-
561
-			return $threads;
562
-		}
492
+        public function treeForNode($id, $options = array()) {
493
+            $options += [
494
+                'root' => false,
495
+                'complete' => false
496
+            ];
497
+
498
+            if ($options['root']) {
499
+                $tid = $id;
500
+            } else {
501
+                $tid = $this->getThreadId($id);
502
+            }
503
+
504
+            $fields = null;
505
+            if ($options['complete']) {
506
+                $fields = array_merge($this->threadLineFieldList, $this->showEntryFieldListAdditional);
507
+            }
508
+
509
+            $tree = $this->treesForThreads([$tid], null, $fields);
510
+
511
+            if ((int)$tid !== (int)$id) {
512
+                $tree = $this->treeGetSubtree($tree, $id);
513
+            }
514
+
515
+            return $tree;
516
+        }
517
+
518
+        /**
519
+         * trees for multiple tids
520
+         *
521
+         * @param $ids
522
+         * @param null $order
523
+         * @param null $fieldlist
524
+         * @return array|bool false if no threads or array with Posting
525
+         */
526
+        public function treesForThreads($ids, $order = null, $fieldlist = null) {
527
+            if (empty($ids)) {
528
+                return [];
529
+            }
530
+
531
+            Stopwatch::start('Model->Entries->treeForThreads() DB');
532
+
533
+            if (empty($order)) {
534
+                $order = 'last_answer ASC';
535
+            }
536
+
537
+            if ($fieldlist === null) {
538
+                $fieldlist = $this->threadLineFieldList;
539
+            }
540
+
541
+            $entries = $this->_getThreadEntries(
542
+                $ids,
543
+                ['order' => $order, 'fields' => $fieldlist]
544
+            );
545
+
546
+            Stopwatch::stop('Model->Entries->treeForThreads() DB');
547
+            Stopwatch::start('Model->Entries->treeForThreads() CPU');
548
+
549
+            $threads = false;
550
+            if ($entries) {
551
+                $threads = [];
552
+                $entries = $this->treeBuild($entries);
553
+                foreach ($entries as $thread) {
554
+                    $id = (int)$thread['Entry']['tid'];
555
+                    $threads[$id] = $thread;
556
+                }
557
+            }
558
+
559
+            Stopwatch::stop('Model->Entries->treeForThreads() CPU');
560
+
561
+            return $threads;
562
+        }
563 563
 
564 564
 /**
565 565
  * @param       $tid
@@ -574,82 +574,82 @@  discard block
 block discarded – undo
574 574
  *  )
575 575
  * </pre>
576 576
  */
577
-		protected function _getThreadEntries($tid, array $params = []) {
578
-			$params += [
579
-				'fields' => $this->threadLineFieldList,
580
-				'order' => 'last_answer ASC'
581
-			];
582
-			$threads = $this->find(
583
-				'all',
584
-				[
585
-					'conditions' => ['tid' => $tid],
586
-					'contain' => ['User', 'Category'],
587
-					'fields' => $params['fields'],
588
-					'order' => $params['order']
589
-				]
590
-			);
591
-
592
-			return $threads;
593
-		}
594
-
595
-		/**
596
-		 * Marks a sub-entry as solution to a root entry
597
-		 *
598
-		 * @param $id
599
-		 * @return bool
600
-		 * @throws InvalidArgumentException
601
-		 * @throws ForbiddenException
602
-		 */
603
-		public function toggleSolve($id) {
604
-			$entry = $this->get($id);
605
-			if (empty($entry) || $this->isRoot($entry)) {
606
-				throw new InvalidArgumentException;
607
-			}
608
-
609
-			$root = $this->get($entry['Entry']['tid']);
610
-			if ((int)$root['User']['id'] !== $this->CurrentUser->getId()) {
611
-				throw new ForbiddenException;
612
-			}
613
-
614
-			if ($entry[$this->alias]['solves']) {
615
-				$value = 0;
616
-			} else {
617
-				$value = $entry[$this->alias]['tid'];
618
-			}
619
-			$this->id = $id;
620
-			$success = $this->saveField('solves', $value);
621
-			if (!$success) {
622
-				return $success;
623
-			}
624
-			$this->_dispatchEvent('Model.Entry.update',
625
-					['subject' => $id, 'data' => $entry]);
626
-			$entry[$this->alias]['solves'] = $value;
627
-			return $success;
628
-		}
629
-
630
-		public function toggle($key) {
631
-			$result = parent::toggle($key);
632
-			if ($key === 'locked') {
633
-				$this->_threadLock($result);
634
-			}
635
-
636
-			$this->contain();
637
-			$entry = $this->read();
638
-
639
-			$this->_dispatchEvent(
640
-				'Model.Entry.update',
641
-				[
642
-					'subject' => $entry[$this->alias]['id'],
643
-					'data' => $entry
644
-				]
645
-			);
646
-
647
-			return $result;
648
-		}
649
-
650
-		public function beforeFind($queryData) {
651
-			parent::beforeFind($queryData);
652
-			/*
577
+        protected function _getThreadEntries($tid, array $params = []) {
578
+            $params += [
579
+                'fields' => $this->threadLineFieldList,
580
+                'order' => 'last_answer ASC'
581
+            ];
582
+            $threads = $this->find(
583
+                'all',
584
+                [
585
+                    'conditions' => ['tid' => $tid],
586
+                    'contain' => ['User', 'Category'],
587
+                    'fields' => $params['fields'],
588
+                    'order' => $params['order']
589
+                ]
590
+            );
591
+
592
+            return $threads;
593
+        }
594
+
595
+        /**
596
+         * Marks a sub-entry as solution to a root entry
597
+         *
598
+         * @param $id
599
+         * @return bool
600
+         * @throws InvalidArgumentException
601
+         * @throws ForbiddenException
602
+         */
603
+        public function toggleSolve($id) {
604
+            $entry = $this->get($id);
605
+            if (empty($entry) || $this->isRoot($entry)) {
606
+                throw new InvalidArgumentException;
607
+            }
608
+
609
+            $root = $this->get($entry['Entry']['tid']);
610
+            if ((int)$root['User']['id'] !== $this->CurrentUser->getId()) {
611
+                throw new ForbiddenException;
612
+            }
613
+
614
+            if ($entry[$this->alias]['solves']) {
615
+                $value = 0;
616
+            } else {
617
+                $value = $entry[$this->alias]['tid'];
618
+            }
619
+            $this->id = $id;
620
+            $success = $this->saveField('solves', $value);
621
+            if (!$success) {
622
+                return $success;
623
+            }
624
+            $this->_dispatchEvent('Model.Entry.update',
625
+                    ['subject' => $id, 'data' => $entry]);
626
+            $entry[$this->alias]['solves'] = $value;
627
+            return $success;
628
+        }
629
+
630
+        public function toggle($key) {
631
+            $result = parent::toggle($key);
632
+            if ($key === 'locked') {
633
+                $this->_threadLock($result);
634
+            }
635
+
636
+            $this->contain();
637
+            $entry = $this->read();
638
+
639
+            $this->_dispatchEvent(
640
+                'Model.Entry.update',
641
+                [
642
+                    'subject' => $entry[$this->alias]['id'],
643
+                    'data' => $entry
644
+                ]
645
+            );
646
+
647
+            return $result;
648
+        }
649
+
650
+        public function beforeFind($queryData) {
651
+            parent::beforeFind($queryData);
652
+            /*
653 653
 				* workarround for possible cakephp join error for associated tables
654 654
 				* and virtual fields
655 655
 				*
@@ -659,17 +659,17 @@  discard block
 block discarded – undo
659 659
 				*
660 660
 				* checkout in cakephp mailing list/bug tracker
661 661
 				*/
662
-			$this->User->virtualFields = null;
663
-		}
662
+            $this->User->virtualFields = null;
663
+        }
664 664
 
665
-		public function beforeValidate($options = array()) {
666
-			parent::beforeValidate($options);
665
+        public function beforeValidate($options = array()) {
666
+            parent::beforeValidate($options);
667 667
 
668
-			//* in n/t posting delete unnecessary body text
669
-			if (isset($this->data['Entry']['text'])) {
670
-				$this->data['Entry']['text'] = rtrim($this->data['Entry']['text']);
671
-			}
672
-		}
668
+            //* in n/t posting delete unnecessary body text
669
+            if (isset($this->data['Entry']['text'])) {
670
+                $this->data['Entry']['text'] = rtrim($this->data['Entry']['text']);
671
+            }
672
+        }
673 673
 
674 674
 /**
675 675
  * Deletes entry and all it's subentries and associated data
@@ -677,43 +677,43 @@  discard block
 block discarded – undo
677 677
  * @return bool
678 678
  * @throws Exception
679 679
  */
680
-		public function deleteNode($id = null) {
681
-			if (empty($id)) {
682
-				$id = $this->id;
683
-			}
684
-
685
-			$this->contain();
686
-			$entry = $this->findById($id);
687
-
688
-			if (empty($entry)) {
689
-				throw new Exception;
690
-			}
691
-
692
-			$_idsToDelete = $this->getIdsForNode($id);
693
-			$success = $this->deleteAll(
694
-				[$this->alias . '.id' => $_idsToDelete],
695
-				true,
696
-				true
697
-			);
698
-
699
-			if ($success):
700
-				if ($this->isRoot($entry)) {
701
-					$this->Category->id = $entry['Entry']['category_id'];
702
-					$this->Category->updateThreadCounter();
703
-					$this->Esevent->deleteSubject($id, 'thread');
704
-				}
705
-				foreach ($_idsToDelete as $_entryId) {
706
-					$this->Esevent->deleteSubject($_entryId, 'entry');
707
-				}
708
-
709
-				$this->_dispatchEvent(
710
-					'Model.Thread.change',
711
-					['subject' => $entry[$this->alias]['tid']]
712
-				);
713
-			endif;
714
-
715
-			return $success;
716
-		}
680
+        public function deleteNode($id = null) {
681
+            if (empty($id)) {
682
+                $id = $this->id;
683
+            }
684
+
685
+            $this->contain();
686
+            $entry = $this->findById($id);
687
+
688
+            if (empty($entry)) {
689
+                throw new Exception;
690
+            }
691
+
692
+            $_idsToDelete = $this->getIdsForNode($id);
693
+            $success = $this->deleteAll(
694
+                [$this->alias . '.id' => $_idsToDelete],
695
+                true,
696
+                true
697
+            );
698
+
699
+            if ($success):
700
+                if ($this->isRoot($entry)) {
701
+                    $this->Category->id = $entry['Entry']['category_id'];
702
+                    $this->Category->updateThreadCounter();
703
+                    $this->Esevent->deleteSubject($id, 'thread');
704
+                }
705
+                foreach ($_idsToDelete as $_entryId) {
706
+                    $this->Esevent->deleteSubject($_entryId, 'entry');
707
+                }
708
+
709
+                $this->_dispatchEvent(
710
+                    'Model.Thread.change',
711
+                    ['subject' => $entry[$this->alias]['tid']]
712
+                );
713
+            endif;
714
+
715
+            return $success;
716
+        }
717 717
 
718 718
 /**
719 719
  * Get the ID of all subentries of and including entry $id
@@ -721,16 +721,16 @@  discard block
 block discarded – undo
721 721
  * @param int $id
722 722
  * @return array Ids
723 723
  */
724
-		public function getIdsForNode($id) {
725
-			$subthread = $this->treeForNode($id);
726
-			$func = function (&$tree, &$entry) {
727
-				$tree['ids'][] = (int)$entry['Entry']['id'];
728
-			};
729
-			Entry::mapTreeElements($subthread, $func);
730
-			sort($subthread['ids']);
724
+        public function getIdsForNode($id) {
725
+            $subthread = $this->treeForNode($id);
726
+            $func = function (&$tree, &$entry) {
727
+                $tree['ids'][] = (int)$entry['Entry']['id'];
728
+            };
729
+            Entry::mapTreeElements($subthread, $func);
730
+            sort($subthread['ids']);
731 731
 
732
-			return $subthread['ids'];
733
-		}
732
+            return $subthread['ids'];
733
+        }
734 734
 
735 735
 /**
736 736
  * Anonymizes the entries for a user
@@ -739,24 +739,24 @@  discard block
 block discarded – undo
739 739
  *
740 740
  * @return bool success
741 741
  */
742
-		public function anonymizeEntriesFromUser($userId) {
743
-			// remove username from all entries and reassign to anonyme user
744
-			$success = $this->updateAll(
745
-				[
746
-					'Entry.name' => "NULL",
747
-					'Entry.edited_by' => "NULL",
748
-					'Entry.ip' => "NULL",
749
-					'Entry.user_id' => 0,
750
-				],
751
-				['Entry.user_id' => $userId]
752
-			);
753
-
754
-			if ($success) {
755
-				$this->_dispatchEvent('Cmd.Cache.clear', ['cache' => 'Thread']);
756
-			}
757
-
758
-			return $success;
759
-		}
742
+        public function anonymizeEntriesFromUser($userId) {
743
+            // remove username from all entries and reassign to anonyme user
744
+            $success = $this->updateAll(
745
+                [
746
+                    'Entry.name' => "NULL",
747
+                    'Entry.edited_by' => "NULL",
748
+                    'Entry.ip' => "NULL",
749
+                    'Entry.user_id' => 0,
750
+                ],
751
+                ['Entry.user_id' => $userId]
752
+            );
753
+
754
+            if ($success) {
755
+                $this->_dispatchEvent('Cmd.Cache.clear', ['cache' => 'Thread']);
756
+            }
757
+
758
+            return $success;
759
+        }
760 760
 
761 761
 /**
762 762
  * Maps all elements in $tree to function $func
@@ -768,23 +768,23 @@  discard block
 block discarded – undo
768 768
  *
769 769
  * @return string
770 770
  */
771
-		public static function mapTreeElements(&$leafs, callable $func, $context = null, &$tree = null) {
772
-			if ($tree === null) {
773
-				$tree = & $leafs;
774
-			}
775
-			foreach ($leafs as $leaf):
776
-				$result = $func($tree, $leaf, $context);
777
-				if ($result === 'break') {
778
-					return 'break';
779
-				}
780
-				if (isset($leaf['_children'])) {
781
-					$result = self::mapTreeElements($leaf['_children'], $func, $context, $tree);
782
-					if ($result === 'break') {
783
-						return 'break';
784
-					}
785
-				}
786
-			endforeach;
787
-		}
771
+        public static function mapTreeElements(&$leafs, callable $func, $context = null, &$tree = null) {
772
+            if ($tree === null) {
773
+                $tree = & $leafs;
774
+            }
775
+            foreach ($leafs as $leaf):
776
+                $result = $func($tree, $leaf, $context);
777
+                if ($result === 'break') {
778
+                    return 'break';
779
+                }
780
+                if (isset($leaf['_children'])) {
781
+                    $result = self::mapTreeElements($leaf['_children'], $func, $context, $tree);
782
+                    if ($result === 'break') {
783
+                        return 'break';
784
+                    }
785
+                }
786
+            endforeach;
787
+        }
788 788
 
789 789
 /**
790 790
  * Merge thread on to entry $targetId
@@ -792,74 +792,74 @@  discard block
 block discarded – undo
792 792
  * @param int $targetId id of the entry the thread should be appended to
793 793
  * @return bool true if merge was successfull false otherwise
794 794
  */
795
-		public function threadMerge($targetId) {
796
-			$threadIdSource = $this->id;
797
-
798
-			$this->contain();
799
-			$sourceEntry = $this->findById($threadIdSource);
800
-
801
-			// check that source is thread and not an entry
802
-			if ($sourceEntry[$this->alias]['pid'] != 0) {
803
-				return false;
804
-			}
805
-
806
-			$this->contain();
807
-			$targetEntry = $this->findById($targetId);
808
-
809
-			// check that target exists
810
-			if (!$targetEntry) {
811
-				return false;
812
-			}
813
-
814
-			// check that a thread is not merged onto itself
815
-			if ($targetEntry[$this->alias]['tid'] === $sourceEntry[$this->alias]['tid']) {
816
-				return false;
817
-			}
818
-
819
-			// set target entry as new parent entry
820
-			$this->data = [];
821
-			$this->set('pid', $targetEntry[$this->alias]['id']);
822
-			if ($this->save()) {
823
-				// associate all entries in source thread to target thread
824
-				$this->updateAll(
825
-					['tid' => $targetEntry[$this->alias]['tid']],
826
-					['tid' => $this->id]
827
-				);
828
-
829
-				// appended source entries get category of target thread
830
-				$this->_threadChangeCategory(
831
-					$targetEntry[$this->alias]['tid'],
832
-					$targetEntry[$this->alias]['category_id']
833
-				);
834
-
835
-				// update target thread last answer if source is newer
836
-				$sourceLastAnswer = $this->field('last_answer');
837
-				if (strtotime($sourceLastAnswer) > strtotime($targetEntry[$this->alias]['last_answer'])) {
838
-					$this->id = $targetEntry[$this->alias]['tid'];
839
-					$this->set('last_answer', $sourceLastAnswer);
840
-					$this->save();
841
-				}
842
-
843
-				// propagate pinned property from target to source
844
-				$isTargetPinned = (bool)$targetEntry[$this->alias]['locked'];
845
-				if ($sourceEntry[$this->alias]['locked'] !== $isTargetPinned) {
846
-					$this->id = $targetEntry[$this->alias]['tid'];
847
-					$this->_threadLock($isTargetPinned);
848
-				}
849
-
850
-				$this->Esevent->transferSubjectForEventType(
851
-					$threadIdSource,
852
-					$targetEntry[$this->alias]['tid'],
853
-					'thread'
854
-				);
855
-				$this->_dispatchEvent(
856
-					'Model.Thread.change',
857
-					['subject' => $targetEntry[$this->alias]['tid']]
858
-				);
859
-				return true;
860
-			}
861
-			return false;
862
-		}
795
+        public function threadMerge($targetId) {
796
+            $threadIdSource = $this->id;
797
+
798
+            $this->contain();
799
+            $sourceEntry = $this->findById($threadIdSource);
800
+
801
+            // check that source is thread and not an entry
802
+            if ($sourceEntry[$this->alias]['pid'] != 0) {
803
+                return false;
804
+            }
805
+
806
+            $this->contain();
807
+            $targetEntry = $this->findById($targetId);
808
+
809
+            // check that target exists
810
+            if (!$targetEntry) {
811
+                return false;
812
+            }
813
+
814
+            // check that a thread is not merged onto itself
815
+            if ($targetEntry[$this->alias]['tid'] === $sourceEntry[$this->alias]['tid']) {
816
+                return false;
817
+            }
818
+
819
+            // set target entry as new parent entry
820
+            $this->data = [];
821
+            $this->set('pid', $targetEntry[$this->alias]['id']);
822
+            if ($this->save()) {
823
+                // associate all entries in source thread to target thread
824
+                $this->updateAll(
825
+                    ['tid' => $targetEntry[$this->alias]['tid']],
826
+                    ['tid' => $this->id]
827
+                );
828
+
829
+                // appended source entries get category of target thread
830
+                $this->_threadChangeCategory(
831
+                    $targetEntry[$this->alias]['tid'],
832
+                    $targetEntry[$this->alias]['category_id']
833
+                );
834
+
835
+                // update target thread last answer if source is newer
836
+                $sourceLastAnswer = $this->field('last_answer');
837
+                if (strtotime($sourceLastAnswer) > strtotime($targetEntry[$this->alias]['last_answer'])) {
838
+                    $this->id = $targetEntry[$this->alias]['tid'];
839
+                    $this->set('last_answer', $sourceLastAnswer);
840
+                    $this->save();
841
+                }
842
+
843
+                // propagate pinned property from target to source
844
+                $isTargetPinned = (bool)$targetEntry[$this->alias]['locked'];
845
+                if ($sourceEntry[$this->alias]['locked'] !== $isTargetPinned) {
846
+                    $this->id = $targetEntry[$this->alias]['tid'];
847
+                    $this->_threadLock($isTargetPinned);
848
+                }
849
+
850
+                $this->Esevent->transferSubjectForEventType(
851
+                    $threadIdSource,
852
+                    $targetEntry[$this->alias]['tid'],
853
+                    'thread'
854
+                );
855
+                $this->_dispatchEvent(
856
+                    'Model.Thread.change',
857
+                    ['subject' => $targetEntry[$this->alias]['tid']]
858
+                );
859
+                return true;
860
+            }
861
+            return false;
862
+        }
863 863
 
864 864
 /**
865 865
  * Test if entry is thread-root
@@ -871,36 +871,36 @@  discard block
 block discarded – undo
871 871
  * @return mixed
872 872
  * @throws InvalidArgumentException
873 873
  */
874
-		public function isRoot($id = null) {
875
-			if ($id === null) {
876
-				$id = $this->id;
877
-			}
878
-
879
-			$md5 = md5(serialize($id));
880
-			if (isset($this->_isRoot[$md5]) === false) {
881
-				// $id was $entry array
882
-				if (is_array($id) && isset($id[$this->alias]['pid'])) {
883
-					$entry = $id;
884
-				} else {
885
-					if (is_array($id) && isset($id[$this->alias]['id'])) {
886
-						$id = $id[$this->alias]['id'];
887
-					} elseif (empty($id)) {
888
-						throw new InvalidArgumentException();
889
-					}
890
-					$entry = $this->find(
891
-						'first',
892
-						array(
893
-							'contain' => false,
894
-							'conditions' => array(
895
-								'id' => $id,
896
-							)
897
-						)
898
-					);
899
-				}
900
-				$this->_isRoot[$md5] = empty($entry[$this->alias]['pid']);
901
-			}
902
-			return $this->_isRoot[$md5];
903
-		}
874
+        public function isRoot($id = null) {
875
+            if ($id === null) {
876
+                $id = $this->id;
877
+            }
878
+
879
+            $md5 = md5(serialize($id));
880
+            if (isset($this->_isRoot[$md5]) === false) {
881
+                // $id was $entry array
882
+                if (is_array($id) && isset($id[$this->alias]['pid'])) {
883
+                    $entry = $id;
884
+                } else {
885
+                    if (is_array($id) && isset($id[$this->alias]['id'])) {
886
+                        $id = $id[$this->alias]['id'];
887
+                    } elseif (empty($id)) {
888
+                        throw new InvalidArgumentException();
889
+                    }
890
+                    $entry = $this->find(
891
+                        'first',
892
+                        array(
893
+                            'contain' => false,
894
+                            'conditions' => array(
895
+                                'id' => $id,
896
+                            )
897
+                        )
898
+                    );
899
+                }
900
+                $this->_isRoot[$md5] = empty($entry[$this->alias]['pid']);
901
+            }
902
+            return $this->_isRoot[$md5];
903
+        }
904 904
 
905 905
 /**
906 906
  * Preprocesses entry data before saving it
@@ -911,85 +911,85 @@  discard block
 block discarded – undo
911 911
  * @throws InvalidArgumentException
912 912
  * @throws ForbiddenException
913 913
  */
914
-		public function prepare(&$data, array $options = []) {
915
-			$options += [
916
-				'isRoot' => null
917
-			];
918
-
919
-			if (isset($options['preFilterFields'])) {
920
-				$org = $data;
921
-				$this->filterFields($data, $options['preFilterFields']);
922
-				if (isset($org['Event'])) {
923
-					$data['Event'] = $org['Event'];
924
-				}
925
-			}
926
-			unset($options['preFilterFields']);
927
-
928
-			$isRoot = $options['isRoot'];
929
-			unset($options['isRoot']);
930
-
931
-			if ($isRoot === null) {
932
-				$isRoot = $this->isRoot($data);
933
-			}
934
-			// adds info from parent entry to an answer
935
-			if ($isRoot === false) {
936
-				if (!isset($data[$this->alias]['pid'])) {
937
-					$pid = $this->getParentId($data[$this->alias]['id']);
938
-				} else {
939
-					$pid = $data[$this->alias]['pid'];
940
-				}
941
-				$parent = $this->get($pid, true);
942
-				if ($parent === false) {
943
-					throw new InvalidArgumentException;
944
-				}
945
-
946
-				// @todo highly @bogus should be a validator?
947
-				$parentPosting = $this->dic->newInstance('\Saito\Posting\Posting', ['rawData' => $parent]);
948
-				if ($parentPosting->isAnsweringForbidden()) {
949
-					throw new ForbiddenException;
950
-				}
951
-
952
-				// if new subject is empty use the parent's subject
953
-				if (empty($data[$this->alias]['subject'])) {
954
-					$data[$this->alias]['subject'] = $parent[$this->alias]['subject'];
955
-				}
956
-
957
-				$data[$this->alias]['tid'] = $parent[$this->alias]['tid'];
958
-				$data[$this->alias]['category_id'] = $parent[$this->alias]['category_id'];
959
-			}
960
-
961
-			//= markup preprocessing
962
-			if (empty($data[$this->alias]['text']) === false) {
963
-				$data[$this->alias]['text'] = $this->prepareMarkup($data[$this->alias]['text']);
964
-			}
965
-		}
966
-
967
-		protected function _findEntry($state, $query, $results = []) {
968
-			if ($state === 'before') {
969
-				$query['contain'] = ['User', 'Category'];
970
-				$query['fields'] = array_merge($this->threadLineFieldList, $this->showEntryFieldListAdditional);
971
-				return $query;
972
-			}
973
-			if ($results) {
974
-				return $results[0];
975
-			}
976
-			return $results;
977
-		}
914
+        public function prepare(&$data, array $options = []) {
915
+            $options += [
916
+                'isRoot' => null
917
+            ];
918
+
919
+            if (isset($options['preFilterFields'])) {
920
+                $org = $data;
921
+                $this->filterFields($data, $options['preFilterFields']);
922
+                if (isset($org['Event'])) {
923
+                    $data['Event'] = $org['Event'];
924
+                }
925
+            }
926
+            unset($options['preFilterFields']);
927
+
928
+            $isRoot = $options['isRoot'];
929
+            unset($options['isRoot']);
930
+
931
+            if ($isRoot === null) {
932
+                $isRoot = $this->isRoot($data);
933
+            }
934
+            // adds info from parent entry to an answer
935
+            if ($isRoot === false) {
936
+                if (!isset($data[$this->alias]['pid'])) {
937
+                    $pid = $this->getParentId($data[$this->alias]['id']);
938
+                } else {
939
+                    $pid = $data[$this->alias]['pid'];
940
+                }
941
+                $parent = $this->get($pid, true);
942
+                if ($parent === false) {
943
+                    throw new InvalidArgumentException;
944
+                }
945
+
946
+                // @todo highly @bogus should be a validator?
947
+                $parentPosting = $this->dic->newInstance('\Saito\Posting\Posting', ['rawData' => $parent]);
948
+                if ($parentPosting->isAnsweringForbidden()) {
949
+                    throw new ForbiddenException;
950
+                }
951
+
952
+                // if new subject is empty use the parent's subject
953
+                if (empty($data[$this->alias]['subject'])) {
954
+                    $data[$this->alias]['subject'] = $parent[$this->alias]['subject'];
955
+                }
956
+
957
+                $data[$this->alias]['tid'] = $parent[$this->alias]['tid'];
958
+                $data[$this->alias]['category_id'] = $parent[$this->alias]['category_id'];
959
+            }
960
+
961
+            //= markup preprocessing
962
+            if (empty($data[$this->alias]['text']) === false) {
963
+                $data[$this->alias]['text'] = $this->prepareMarkup($data[$this->alias]['text']);
964
+            }
965
+        }
966
+
967
+        protected function _findEntry($state, $query, $results = []) {
968
+            if ($state === 'before') {
969
+                $query['contain'] = ['User', 'Category'];
970
+                $query['fields'] = array_merge($this->threadLineFieldList, $this->showEntryFieldListAdditional);
971
+                return $query;
972
+            }
973
+            if ($results) {
974
+                return $results[0];
975
+            }
976
+            return $results;
977
+        }
978 978
 
979 979
 /**
980 980
  * Implements the custom find type 'feed'
981 981
  *
982 982
  * Add parameters for generating a rss/json-feed with find('feed', …)
983 983
  */
984
-		protected function _findFeed($state, $query, $results = array()) {
985
-			if ($state == 'before') {
986
-				$query['contain'] = array('User');
987
-				$query['fields'] = $this->_allowedPublicOutputFields;
988
-				$query['limit'] = 10;
989
-				return $query;
990
-			}
991
-			return $results;
992
-		}
984
+        protected function _findFeed($state, $query, $results = array()) {
985
+            if ($state == 'before') {
986
+                $query['contain'] = array('User');
987
+                $query['fields'] = $this->_allowedPublicOutputFields;
988
+                $query['limit'] = 10;
989
+                return $query;
990
+            }
991
+            return $results;
992
+        }
993 993
 
994 994
 /**
995 995
  * Locks or unlocks a whole thread
@@ -998,57 +998,57 @@  discard block
 block discarded – undo
998 998
  *
999 999
  * @param bool $value
1000 1000
  */
1001
-		protected function _threadLock($value) {
1002
-			$tid = $this->field('tid');
1003
-			$this->contain();
1004
-			// @bogus throws error on $value = false
1005
-			$value = $value ? 1 : 0;
1006
-			$this->updateAll(['locked' => $value], ['tid' => $tid]);
1007
-		}
1008
-
1009
-		public function paginateCount($conditions, $recursive, $extra) {
1010
-			if (isset($extra['getInitialThreads'])) {
1011
-				$this->Category->contain();
1012
-				$categories = $this->Category->find(
1013
-					'all',
1014
-					[
1015
-						'conditions' => array('id' => $conditions['Entry.category_id']),
1016
-						'fields' => array('thread_count')
1017
-					]
1018
-				);
1019
-				$count = array_sum(Set::extract('/Category/thread_count', $categories));
1020
-			} else {
1021
-				$parameters = array('conditions' => $conditions);
1022
-				if ($recursive != $this->recursive) {
1023
-					$parameters['recursive'] = $recursive;
1024
-				}
1025
-				$count = $this->find('count', array_merge($parameters, $extra));
1026
-			}
1027
-			return $count;
1028
-		}
1029
-
1030
-		public function beforeSave($options = array()) {
1031
-			$success = true;
1032
-
1033
-			//# change category of thread if category of root entry changed
1034
-			$modified = !empty($this->id);
1035
-			if (isset($this->data[$this->alias]['category_id']) && $modified) {
1036
-				$oldEntry = $this->find('first',
1037
-					['contain' => false, 'conditions' => ['Entry.id' => $this->id]]);
1038
-
1039
-				if ($oldEntry && (int)$oldEntry[$this->alias]['pid'] === 0) {
1040
-					$categoryChanged = (int)$this->data[$this->alias]['category_id'] !== (int)$oldEntry[$this->alias]['category_id'];
1041
-					if ($categoryChanged) {
1042
-						$success = $success && $this->_threadChangeCategory(
1043
-								$oldEntry[$this->alias]['tid'],
1044
-								$this->data[$this->alias]['category_id']
1045
-							);
1046
-					}
1047
-				}
1048
-			}
1049
-
1050
-			return $success && parent::beforeSave($options);
1051
-		}
1001
+        protected function _threadLock($value) {
1002
+            $tid = $this->field('tid');
1003
+            $this->contain();
1004
+            // @bogus throws error on $value = false
1005
+            $value = $value ? 1 : 0;
1006
+            $this->updateAll(['locked' => $value], ['tid' => $tid]);
1007
+        }
1008
+
1009
+        public function paginateCount($conditions, $recursive, $extra) {
1010
+            if (isset($extra['getInitialThreads'])) {
1011
+                $this->Category->contain();
1012
+                $categories = $this->Category->find(
1013
+                    'all',
1014
+                    [
1015
+                        'conditions' => array('id' => $conditions['Entry.category_id']),
1016
+                        'fields' => array('thread_count')
1017
+                    ]
1018
+                );
1019
+                $count = array_sum(Set::extract('/Category/thread_count', $categories));
1020
+            } else {
1021
+                $parameters = array('conditions' => $conditions);
1022
+                if ($recursive != $this->recursive) {
1023
+                    $parameters['recursive'] = $recursive;
1024
+                }
1025
+                $count = $this->find('count', array_merge($parameters, $extra));
1026
+            }
1027
+            return $count;
1028
+        }
1029
+
1030
+        public function beforeSave($options = array()) {
1031
+            $success = true;
1032
+
1033
+            //# change category of thread if category of root entry changed
1034
+            $modified = !empty($this->id);
1035
+            if (isset($this->data[$this->alias]['category_id']) && $modified) {
1036
+                $oldEntry = $this->find('first',
1037
+                    ['contain' => false, 'conditions' => ['Entry.id' => $this->id]]);
1038
+
1039
+                if ($oldEntry && (int)$oldEntry[$this->alias]['pid'] === 0) {
1040
+                    $categoryChanged = (int)$this->data[$this->alias]['category_id'] !== (int)$oldEntry[$this->alias]['category_id'];
1041
+                    if ($categoryChanged) {
1042
+                        $success = $success && $this->_threadChangeCategory(
1043
+                                $oldEntry[$this->alias]['tid'],
1044
+                                $this->data[$this->alias]['category_id']
1045
+                            );
1046
+                    }
1047
+                }
1048
+            }
1049
+
1050
+            return $success && parent::beforeSave($options);
1051
+        }
1052 1052
 
1053 1053
 /**
1054 1054
  * check that entries are only in existing and allowed categories
@@ -1056,35 +1056,35 @@  discard block
 block discarded – undo
1056 1056
  * @param $check
1057 1057
  * @return bool
1058 1058
  */
1059
-		public function validateCategoryIsAllowed($check) {
1060
-			$availableCategories = $this->CurrentUser->Categories->getAllowed();
1061
-			if (!isset($availableCategories[$check['category_id']])) {
1062
-				return false;
1063
-			}
1064
-			return true;
1065
-		}
1066
-
1067
-		/**
1068
-		 * @param $check
1069
-		 * @return bool
1070
-		 * @throws Exception
1071
-		 */
1072
-		public function validateEditingAllowed($check) {
1073
-			$id = $this->data[$this->alias]['id'];
1074
-			$entry = $this->get($id);
1075
-			if (empty($entry)) {
1076
-				throw new Exception(sprintf('Entry %s not found.', $entry));
1077
-			}
1078
-
1079
-			$posting = $this->dic->newInstance('\Saito\Posting\Posting', ['rawData' => $entry]);
1080
-			$forbidden = $posting->isEditingAsCurrentUserForbidden();
1081
-
1082
-			if (is_bool($forbidden)) {
1083
-				return !$forbidden;
1084
-			} else {
1085
-				return $forbidden;
1086
-			}
1087
-		}
1059
+        public function validateCategoryIsAllowed($check) {
1060
+            $availableCategories = $this->CurrentUser->Categories->getAllowed();
1061
+            if (!isset($availableCategories[$check['category_id']])) {
1062
+                return false;
1063
+            }
1064
+            return true;
1065
+        }
1066
+
1067
+        /**
1068
+         * @param $check
1069
+         * @return bool
1070
+         * @throws Exception
1071
+         */
1072
+        public function validateEditingAllowed($check) {
1073
+            $id = $this->data[$this->alias]['id'];
1074
+            $entry = $this->get($id);
1075
+            if (empty($entry)) {
1076
+                throw new Exception(sprintf('Entry %s not found.', $entry));
1077
+            }
1078
+
1079
+            $posting = $this->dic->newInstance('\Saito\Posting\Posting', ['rawData' => $entry]);
1080
+            $forbidden = $posting->isEditingAsCurrentUserForbidden();
1081
+
1082
+            if (is_bool($forbidden)) {
1083
+                return !$forbidden;
1084
+            } else {
1085
+                return $forbidden;
1086
+            }
1087
+        }
1088 1088
 
1089 1089
 /**
1090 1090
  *
@@ -1097,9 +1097,9 @@  discard block
 block discarded – undo
1097 1097
  * @param $check
1098 1098
  * @return bool
1099 1099
  */
1100
-		public function validateSubjectMaxLength($check) {
1101
-			return mb_strlen($check['subject']) <= $this->_setting('subject_maxlength');
1102
-		}
1100
+        public function validateSubjectMaxLength($check) {
1101
+            return mb_strlen($check['subject']) <= $this->_setting('subject_maxlength');
1102
+        }
1103 1103
 
1104 1104
 /**
1105 1105
  * Changes the category of a thread.
@@ -1113,20 +1113,20 @@  discard block
 block discarded – undo
1113 1113
  * @throws NotFoundException
1114 1114
  * @throws InvalidArgumentException
1115 1115
  */
1116
-		protected function _threadChangeCategory($tid = null, $newCategoryId = null) {
1117
-			if (empty($tid)) {
1118
-				throw new InvalidArgumentException;
1119
-			}
1120
-			$this->Category->contain();
1121
-			$categoryExists = $this->Category->findById($newCategoryId);
1122
-			if (!$categoryExists) {
1123
-				throw new NotFoundException;
1124
-			}
1125
-			$out = $this->updateAll(
1126
-				['Entry.category_id' => $newCategoryId],
1127
-				['Entry.tid' => $tid]
1128
-			);
1129
-			return $out;
1130
-		}
1131
-
1132
-	}
1133 1116
\ No newline at end of file
1117
+        protected function _threadChangeCategory($tid = null, $newCategoryId = null) {
1118
+            if (empty($tid)) {
1119
+                throw new InvalidArgumentException;
1120
+            }
1121
+            $this->Category->contain();
1122
+            $categoryExists = $this->Category->findById($newCategoryId);
1123
+            if (!$categoryExists) {
1124
+                throw new NotFoundException;
1125
+            }
1126
+            $out = $this->updateAll(
1127
+                ['Entry.category_id' => $newCategoryId],
1128
+                ['Entry.tid' => $tid]
1129
+            );
1130
+            return $out;
1131
+        }
1132
+
1133
+    }
1134 1134
\ No newline at end of file
Please login to merge, or discard this patch.
app/Model/Esnotification.php 1 patch
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -8,43 +8,43 @@
 block discarded – undo
8 8
  */
9 9
 class Esnotification extends AppModel {
10 10
 
11
-	//The Associations below have been created with all possible keys, those that are not needed can be removed
11
+    //The Associations below have been created with all possible keys, those that are not needed can be removed
12 12
 
13 13
 /**
14 14
  * belongsTo associations
15 15
  *
16 16
  * @var array
17 17
  */
18
-	public $belongsTo = array(
19
-		'User' => array(
20
-			'className' => 'User',
21
-			'foreignKey' => 'user_id',
22
-			'conditions' => '',
23
-			'fields' => '',
24
-			'order' => ''
25
-		),
26
-		'Esevent' => array(
27
-			'className' => 'Esevent',
28
-			'foreignKey' => 'esevent_id',
29
-			'conditions' => '',
30
-			'fields' => '',
31
-			'order' => ''
32
-		)
33
-	);
18
+    public $belongsTo = array(
19
+        'User' => array(
20
+            'className' => 'User',
21
+            'foreignKey' => 'user_id',
22
+            'conditions' => '',
23
+            'fields' => '',
24
+            'order' => ''
25
+        ),
26
+        'Esevent' => array(
27
+            'className' => 'Esevent',
28
+            'foreignKey' => 'esevent_id',
29
+            'conditions' => '',
30
+            'fields' => '',
31
+            'order' => ''
32
+        )
33
+    );
34 34
 
35
-	public function beforeSave($options = array()) {
36
-		if (empty($this->data[$this->alias]['deactivate'])) {
37
-			$this->data[$this->alias]['deactivate'] = mt_rand(0, 99999999);
38
-		}
35
+    public function beforeSave($options = array()) {
36
+        if (empty($this->data[$this->alias]['deactivate'])) {
37
+            $this->data[$this->alias]['deactivate'] = mt_rand(0, 99999999);
38
+        }
39 39
 
40
-		return parent::beforeSave();
41
-	}
40
+        return parent::beforeSave();
41
+    }
42 42
 
43
-	public function deleteNotificationWithId($id) {
44
-			return $this->delete($id, false);
45
-	}
43
+    public function deleteNotificationWithId($id) {
44
+            return $this->delete($id, false);
45
+    }
46 46
 
47
-	public function deleteAllFromUser($userId) {
48
-		return $this->deleteAll(array('user_id' => $userId), false);
49
-	}
47
+    public function deleteAllFromUser($userId) {
48
+        return $this->deleteAll(array('user_id' => $userId), false);
49
+    }
50 50
 }
Please login to merge, or discard this patch.
app/Model/Behavior/TreeBehavior.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -1,35 +1,35 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-	class TreeBehavior extends ModelBehavior {
4
-
5
-		public function treeGetSubtree(Model $Model, $tree, $_nodeId) {
6
-			$func = function (&$tree, &$entry, $_nodeId) {
7
-				if ((int)$entry['Entry']['id'] === (int)$_nodeId) {
8
-					$tree = array($entry);
9
-					return 'break';
10
-				}
11
-			};
12
-			Entry::mapTreeElements($tree, $func, $_nodeId);
13
-			return $tree;
14
-		}
15
-
16
-		public function treeBuild(Model $Model, $threads) {
17
-			$tree = array();
18
-			foreach ($threads as $thread) {
19
-				$id = $thread[$Model->alias]['id'];
20
-				$pid = $thread[$Model->alias]['pid'];
21
-				$tree[$id] = isset($tree[$id]) ? $tree[$id] + $thread : $thread;
22
-				$tree[$pid]['_children'][] = &$tree[$id];
23
-			}
24
-
25
-			// It's possible to do uasort before tree build and  get the same results,
26
-			// without _sortTreesAfterTime
27
-			// but then *all* entries have to be sorted whereas now only subthreads with childs
28
-			// are sorted. So using _sortTreesAfterTime is actually faster in praxis.
29
-			$_sortedTrees = $this->_sortTreesAfterTime($tree[0]['_children']);
30
-
31
-			return $_sortedTrees;
32
-		}
3
+    class TreeBehavior extends ModelBehavior {
4
+
5
+        public function treeGetSubtree(Model $Model, $tree, $_nodeId) {
6
+            $func = function (&$tree, &$entry, $_nodeId) {
7
+                if ((int)$entry['Entry']['id'] === (int)$_nodeId) {
8
+                    $tree = array($entry);
9
+                    return 'break';
10
+                }
11
+            };
12
+            Entry::mapTreeElements($tree, $func, $_nodeId);
13
+            return $tree;
14
+        }
15
+
16
+        public function treeBuild(Model $Model, $threads) {
17
+            $tree = array();
18
+            foreach ($threads as $thread) {
19
+                $id = $thread[$Model->alias]['id'];
20
+                $pid = $thread[$Model->alias]['pid'];
21
+                $tree[$id] = isset($tree[$id]) ? $tree[$id] + $thread : $thread;
22
+                $tree[$pid]['_children'][] = &$tree[$id];
23
+            }
24
+
25
+            // It's possible to do uasort before tree build and  get the same results,
26
+            // without _sortTreesAfterTime
27
+            // but then *all* entries have to be sorted whereas now only subthreads with childs
28
+            // are sorted. So using _sortTreesAfterTime is actually faster in praxis.
29
+            $_sortedTrees = $this->_sortTreesAfterTime($tree[0]['_children']);
30
+
31
+            return $_sortedTrees;
32
+        }
33 33
 
34 34
 /**
35 35
  * Sort all entries in trees after time
@@ -38,25 +38,25 @@  discard block
 block discarded – undo
38 38
  * @param int $level
39 39
  * @return array
40 40
  */
41
-		protected function _sortTreesAfterTime($in, $level = 0) {
42
-			if ($level > 0) {
43
-				uasort($in, [$this, '_sort']);
44
-			}
45
-
46
-			foreach ($in as $k => $v) {
47
-				if (isset($v['_children'])) {
48
-					$in[$k]['_children'] = $this->_sortTreesAfterTime($v['_children'], $level + 1);
49
-				}
50
-			}
51
-			return $in;
52
-		}
53
-
54
-		protected function _sort($a, $b) {
55
-			if ($a['Entry']['time'] === $b['Entry']['time']) {
56
-				return ($a['Entry']['id'] > $b['Entry']['id']) ? 1 : -1;
57
-			} else {
58
-				return ($a['Entry']['time'] > $b['Entry']['time']) ? 1 : -1;
59
-			}
60
-		}
61
-
62
-	}
41
+        protected function _sortTreesAfterTime($in, $level = 0) {
42
+            if ($level > 0) {
43
+                uasort($in, [$this, '_sort']);
44
+            }
45
+
46
+            foreach ($in as $k => $v) {
47
+                if (isset($v['_children'])) {
48
+                    $in[$k]['_children'] = $this->_sortTreesAfterTime($v['_children'], $level + 1);
49
+                }
50
+            }
51
+            return $in;
52
+        }
53
+
54
+        protected function _sort($a, $b) {
55
+            if ($a['Entry']['time'] === $b['Entry']['time']) {
56
+                return ($a['Entry']['id'] > $b['Entry']['id']) ? 1 : -1;
57
+            } else {
58
+                return ($a['Entry']['time'] > $b['Entry']['time']) ? 1 : -1;
59
+            }
60
+        }
61
+
62
+    }
Please login to merge, or discard this patch.