PageRenderTime 29ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Common/Core/Model.php

http://github.com/forkcms/forkcms
PHP | 349 lines | 189 code | 50 blank | 110 comment | 21 complexity | 549d7c47b2dfc7928dd73bccff7552e9 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, MIT, AGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. namespace Common\Core;
  3. use ForkCMS\App\BaseModel;
  4. use ForkCMS\Utility\Thumbnails;
  5. use InvalidArgumentException;
  6. use RuntimeException;
  7. use Symfony\Component\HttpFoundation\Request;
  8. use Symfony\Component\HttpFoundation\Session\Session;
  9. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  10. use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
  11. use TijsVerkoyen\Akismet\Akismet;
  12. /**
  13. * This class will initiate the frontend-application
  14. */
  15. class Model extends BaseModel
  16. {
  17. const HOME_PAGE_ID = 1;
  18. const ERROR_PAGE_ID = 404;
  19. /**
  20. * Cached modules
  21. *
  22. * @var array
  23. */
  24. protected static $modules = [];
  25. /**
  26. * Add a number to the string
  27. *
  28. * @param string $string The string where the number will be appended to.
  29. *
  30. * @return string
  31. */
  32. public static function addNumber(string $string): string
  33. {
  34. // split
  35. $chunks = explode('-', $string);
  36. // count the chunks
  37. $count = count($chunks);
  38. // get last chunk
  39. $last = $chunks[$count - 1];
  40. // is numeric
  41. if (!\SpoonFilter::isNumeric($last)) {
  42. // not numeric, so add -2
  43. return $string . '-2';
  44. }
  45. // remove last chunk
  46. array_pop($chunks);
  47. // join together, and increment the last one
  48. return implode('-', $chunks) . '-' . ((int) $last + 1);
  49. }
  50. /**
  51. * Generate a totally random but readable/speakable password
  52. *
  53. * @param int $length The maximum length for the password to generate.
  54. * @param bool $uppercaseAllowed Are uppercase letters allowed?
  55. * @param bool $lowercaseAllowed Are lowercase letters allowed?
  56. *
  57. * @return string
  58. */
  59. public static function generatePassword(
  60. int $length = 6,
  61. bool $uppercaseAllowed = true,
  62. bool $lowercaseAllowed = true
  63. ): string {
  64. // list of allowed vowels and vowel sounds
  65. $vowels = ['a', 'e', 'i', 'u', 'ae', 'ea'];
  66. // list of allowed consonants and consonant sounds
  67. $consonants = [
  68. 'b',
  69. 'c',
  70. 'd',
  71. 'g',
  72. 'h',
  73. 'j',
  74. 'k',
  75. 'm',
  76. 'n',
  77. 'p',
  78. 'r',
  79. 's',
  80. 't',
  81. 'u',
  82. 'v',
  83. 'w',
  84. 'tr',
  85. 'cr',
  86. 'fr',
  87. 'dr',
  88. 'wr',
  89. 'pr',
  90. 'th',
  91. 'ch',
  92. 'ph',
  93. 'st',
  94. ];
  95. $consonantsCount = count($consonants);
  96. $vowelsCount = count($vowels);
  97. $pass = '';
  98. $tmp = '';
  99. // create temporary pass
  100. for ($i = 0; $i < $length; ++$i) {
  101. $tmp .= ($consonants[random_int(0, $consonantsCount - 1)] .
  102. $vowels[random_int(0, $vowelsCount - 1)]);
  103. }
  104. // reformat the pass
  105. for ($i = 0; $i < $length; ++$i) {
  106. if (random_int(0, 1) === 1) {
  107. $pass .= mb_strtoupper($tmp[$i]);
  108. continue;
  109. }
  110. $pass .= $tmp[$i];
  111. }
  112. // reformat it again, if uppercase isn't allowed
  113. if (!$uppercaseAllowed) {
  114. $pass = mb_strtolower($pass);
  115. }
  116. // reformat it again, if uppercase isn't allowed
  117. if (!$lowercaseAllowed) {
  118. $pass = mb_strtoupper($pass);
  119. }
  120. // return pass
  121. return $pass;
  122. }
  123. /**
  124. * Generate thumbnails based on the folders in the path
  125. * Use
  126. * - 128x128 as foldername to generate an image where the width will be
  127. * 128px and the height will be 128px
  128. * - 128x as foldername to generate an image where the width will be
  129. * 128px, the height will be calculated based on the aspect ratio.
  130. * - x128 as foldername to generate an image where the height will be
  131. * 128px, the width will be calculated based on the aspect ratio.
  132. *
  133. * @param string $path The path wherein the thumbnail-folders will be stored.
  134. * @param string $sourceFile The location of the source file
  135. *
  136. * @deprecated Please use the service `ForkCMS\Utility\Thumbnails` instead.
  137. */
  138. public static function generateThumbnails(string $path, string $sourceFile): void
  139. {
  140. self::get(Thumbnails::class)->generate($path, $sourceFile);
  141. }
  142. /**
  143. * Delete thumbnails based on the folders in the path
  144. *
  145. * @param string $path The path wherein the thumbnail-folders exist.
  146. * @param string|null $thumbnail The filename to be deleted.
  147. *
  148. * @deprecated Please use the service `ForkCMS\Utility\Thumbnails` instead.
  149. */
  150. public static function deleteThumbnails(string $path, ?string $thumbnail): void
  151. {
  152. self::get(Thumbnails::class)->delete($path, $thumbnail);
  153. }
  154. /**
  155. * Get the thumbnail folders
  156. *
  157. * @param string $path The path
  158. * @param bool $includeSource Should the source-folder be included in the return-array.
  159. *
  160. * @return array
  161. *
  162. * @deprecated Please use the service `ForkCMS\Utility\Thumbnails` instead.
  163. */
  164. public static function getThumbnailFolders(string $path, bool $includeSource = false): array
  165. {
  166. return self::get(Thumbnails::class)->getFolders($path, $includeSource);
  167. }
  168. /**
  169. * Get the UTC date in a specific format. Use this method when inserting dates in the database!
  170. *
  171. * @param string $format The format to return the timestamp in. Default is MySQL datetime format.
  172. * @param int $timestamp The timestamp to use, if not provided the current time will be used.
  173. *
  174. * @return string
  175. */
  176. public static function getUTCDate(string $format = null, int $timestamp = null): string
  177. {
  178. $format = ($format !== null) ? (string) $format : 'Y-m-d H:i:s';
  179. if ($timestamp === null) {
  180. return gmdate($format);
  181. }
  182. return gmdate($format, $timestamp);
  183. }
  184. /**
  185. * Get the UTC timestamp for a date/time object combination.
  186. *
  187. * @param \SpoonFormDate $date An instance of \SpoonFormDate.
  188. * @param \SpoonFormTime $time An instance of \SpoonFormTime.
  189. *
  190. * @throws \Exception If provided $date, $time or both are invalid
  191. *
  192. * @return int
  193. */
  194. public static function getUTCTimestamp(\SpoonFormDate $date, \SpoonFormTime $time = null): int
  195. {
  196. // validate date/time object
  197. if (!$date->isValid() || ($time !== null && !$time->isValid())
  198. ) {
  199. throw new \Exception('You need to provide two objects that actually contain valid data.');
  200. }
  201. $year = gmdate('Y', $date->getTimestamp());
  202. $month = gmdate('m', $date->getTimestamp());
  203. $day = gmdate('j', $date->getTimestamp());
  204. $hour = 0;
  205. $minute = 0;
  206. if ($time !== null) {
  207. // define hour & minute
  208. list($hour, $minute) = explode(':', $time->getValue());
  209. }
  210. // make and return timestamp
  211. return mktime($hour, $minute, 0, $month, $day, $year);
  212. }
  213. public static function getModules(): array
  214. {
  215. // validate cache
  216. if (!empty(self::$modules)) {
  217. return self::$modules;
  218. }
  219. // get all modules
  220. $modules = (array) self::getContainer()->get('database')->getColumn('SELECT m.name FROM modules AS m');
  221. // add modules to the cache
  222. foreach ($modules as $module) {
  223. self::$modules[] = $module;
  224. }
  225. return self::$modules;
  226. }
  227. public static function getRequest(): Request
  228. {
  229. if (!self::requestIsAvailable()) {
  230. throw new RuntimeException('No request available');
  231. }
  232. return self::getContainer()->get('request_stack')->getCurrentRequest();
  233. }
  234. public static function requestIsAvailable(): bool
  235. {
  236. return self::getContainer()->has('request_stack')
  237. && self::getContainer()->get('request_stack')->getCurrentRequest() !== null;
  238. }
  239. protected static function getAkismet(): Akismet
  240. {
  241. $akismetKey = self::get('fork.settings')->get('Core', 'akismet_key');
  242. // invalid key, so we can't detect spam
  243. if (empty($akismetKey)) {
  244. throw new InvalidArgumentException('no akismet key found');
  245. }
  246. $akismet = new Akismet($akismetKey, SITE_URL);
  247. $akismet->setTimeOut(10);
  248. $akismet->setUserAgent('Fork CMS/' . FORK_VERSION);
  249. return $akismet;
  250. }
  251. public static function getSession(): SessionInterface
  252. {
  253. if (!self::requestIsAvailable()) {
  254. return self::getMockSession();
  255. }
  256. $request = self::getRequest();
  257. if ($request->hasSession()) {
  258. return $request->getSession();
  259. }
  260. $session = new Session();
  261. $session->start();
  262. $request->setSession($session);
  263. return $session;
  264. }
  265. /**
  266. * This method will return a mock session that will be only available while the code is running.
  267. * It is used for instance in the console
  268. *
  269. * @deprecated This has been added to fix an issue but should be fixed properly in fork 6.0.0
  270. *
  271. * @return Session
  272. */
  273. private static function getMockSession(): Session
  274. {
  275. if (!self::getContainer()->has('fork.mock.session')) {
  276. self::getContainer()->set('fork.mock.session', new Session(new MockArraySessionStorage()));
  277. }
  278. return self::get('fork.mock.session');
  279. }
  280. /**
  281. * This method returns the filesize in a human readable format according to the value
  282. *
  283. * @param int $fileSize
  284. * @return string
  285. */
  286. public static function prettyPrintFileSize(int $fileSize): string
  287. {
  288. if ($fileSize > 999999999) {
  289. return number_format($fileSize / 1000000000, 2, ',', ' ') . ' GB';
  290. }
  291. if ($fileSize > 999999) {
  292. return number_format($fileSize / 1000000, 2, ',', ' ') . ' MB';
  293. }
  294. if ($fileSize > 999) {
  295. return number_format($fileSize / 1000, 2, ',', ' ') . ' KB';
  296. }
  297. return $fileSize . ' bytes';
  298. }
  299. }