PageRenderTime 42ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/mautic/app/bundles/AssetBundle/Model/AssetModel.php

https://gitlab.com/randydanniswara/website
PHP | 434 lines | 270 code | 60 blank | 104 comment | 49 complexity | 29f9dbd1e9dd710ba92acb8dd14cf686 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Mautic
  4. * @copyright 2014 Mautic Contributors. All rights reserved.
  5. * @author Mautic
  6. * @link http://mautic.org
  7. * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
  8. */
  9. namespace Mautic\AssetBundle\Model;
  10. use Doctrine\ORM\PersistentCollection;
  11. use Mautic\AssetBundle\Event\AssetEvent;
  12. use Mautic\CoreBundle\Entity\IpAddress;
  13. use Mautic\CoreBundle\Helper\InputHelper;
  14. use Mautic\CoreBundle\Model\FormModel;
  15. use Mautic\AssetBundle\Entity\Asset;
  16. use Mautic\AssetBundle\Entity\Download;
  17. use Mautic\AssetBundle\AssetEvents;
  18. use Mautic\EmailBundle\Entity\Email;
  19. use Mautic\LeadBundle\Entity\Lead;
  20. use Symfony\Component\EventDispatcher\Event;
  21. use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
  22. /**
  23. * Class AssetModel
  24. */
  25. class AssetModel extends FormModel
  26. {
  27. /**
  28. * {@inheritdoc}
  29. */
  30. public function saveEntity($entity, $unlock = true)
  31. {
  32. if (empty($this->inConversion)) {
  33. $alias = $entity->getAlias();
  34. if (empty($alias)) {
  35. $alias = $entity->getTitle();
  36. }
  37. $alias = $this->cleanAlias($alias, '', false, '-');
  38. //make sure alias is not already taken
  39. $repo = $this->getRepository();
  40. $testAlias = $alias;
  41. $count = $repo->checkUniqueAlias($testAlias, $entity);
  42. $aliasTag = $count;
  43. while ($count) {
  44. $testAlias = $alias . $aliasTag;
  45. $count = $repo->checkUniqueAlias($testAlias, $entity);
  46. $aliasTag++;
  47. }
  48. if ($testAlias != $alias) {
  49. $alias = $testAlias;
  50. }
  51. $entity->setAlias($alias);
  52. }
  53. //set the author for new asset
  54. if (!$entity->isNew()) {
  55. //increase the revision
  56. $revision = $entity->getRevision();
  57. $revision++;
  58. $entity->setRevision($revision);
  59. }
  60. parent::saveEntity($entity, $unlock);
  61. }
  62. /**
  63. * @param $asset
  64. * @param $request
  65. * @param string $code
  66. * @param array $systemEntry
  67. *
  68. * @throws \Doctrine\ORM\ORMException
  69. */
  70. public function trackDownload($asset, $request = null, $code = '200', $systemEntry = array())
  71. {
  72. // Don't skew results with in-house downloads
  73. if (empty($systemEntry) && !$this->factory->getSecurity()->isAnonymous()) {
  74. return;
  75. }
  76. if ($request == null) {
  77. $request = $this->factory->getRequest();
  78. }
  79. $download = new Download();
  80. $download->setDateDownload(new \Datetime());
  81. /** @var \Mautic\LeadBundle\Model\LeadModel $leadModel */
  82. $leadModel = $this->factory->getModel('lead');
  83. // Download triggered by lead
  84. if (empty($systemEntry)) {
  85. //check for any clickthrough info
  86. $clickthrough = $request->get('ct', false);
  87. if (!empty($clickthrough)) {
  88. $clickthrough = $this->decodeArrayFromUrl($clickthrough);
  89. if (!empty($clickthrough['lead'])) {
  90. $lead = $leadModel->getEntity($clickthrough['lead']);
  91. if ($lead !== null) {
  92. $leadModel->setLeadCookie($clickthrough['lead']);
  93. list($trackingId, $trackingNewlyGenerated) = $leadModel->getTrackingCookie();
  94. $leadClickthrough = true;
  95. $leadModel->setCurrentLead($lead);
  96. }
  97. }
  98. if (!empty($clickthrough['source'])) {
  99. $download->setSource($clickthrough['source'][0]);
  100. $download->setSourceId($clickthrough['source'][1]);
  101. }
  102. if (!empty($clickthrough['email'])) {
  103. $download->setEmail($this->em->getReference('MauticEmailBundle:Email', $clickthrough['email']));
  104. }
  105. }
  106. if (empty($leadClickthrough)) {
  107. list($lead, $trackingId, $trackingNewlyGenerated) = $leadModel->getCurrentLead(true);
  108. }
  109. $download->setLead($lead);
  110. } else {
  111. $trackingId = '';
  112. if (isset($systemEntry['lead'])) {
  113. $lead = $systemEntry['lead'];
  114. if (!$lead instanceof Lead) {
  115. $leadId = is_array($lead) ? $lead['id'] : $lead;
  116. $lead = $this->em->getReference('MauticLeadBundle:Lead', $leadId);
  117. }
  118. $download->setLead($lead);
  119. }
  120. if (!empty($systemEntry['source'])) {
  121. $download->setSource($systemEntry['source'][0]);
  122. $download->setSourceId($systemEntry['source'][1]);
  123. }
  124. if (isset($systemEntry['email'])) {
  125. $email = $systemEntry['email'];
  126. if (!$email instanceof Email) {
  127. $emailId = is_array($email) ? $email['id'] : $email;
  128. $email = $this->em->getReference('MauticEmailBundle:Email', $emailId);
  129. }
  130. $download->setEmail($email);
  131. }
  132. if (isset($systemEntry['tracking_id'])) {
  133. $trackingId = $systemEntry['tracking_id'];
  134. $trackingNewlyGenerated = false;
  135. } elseif ($this->factory->getSecurity()->isAnonymous() && !defined('IN_MAUTIC_CONSOLE')) {
  136. // If the session is anonymous and not triggered via CLI, assume the lead did something to trigger the
  137. // system forced download such as an email
  138. list($trackingId, $trackingNewlyGenerated) = $leadModel->getTrackingCookie();
  139. }
  140. }
  141. $isUnique = true;
  142. if (!empty($trackingNewlyGenerated)) {
  143. // Cookie was just generated so this is definitely a unique download
  144. $isUnique = $trackingNewlyGenerated;
  145. } elseif (!empty($trackingId)) {
  146. // Determine if this is a unique download
  147. $isUnique = $this->getDownloadRepository()->isUniqueDownload($asset->getId(), $trackingId);
  148. }
  149. $download->setTrackingId($trackingId);
  150. if (!empty($asset) && empty($systemEntry)) {
  151. $download->setAsset($asset);
  152. $this->getRepository()->upDownloadCount($asset->getId(), 1, $isUnique);
  153. }
  154. //check for existing IP
  155. $ipAddress = $this->factory->getIpAddress();
  156. $download->setCode($code);
  157. $download->setIpAddress($ipAddress);
  158. $download->setReferer($request->server->get('HTTP_REFERER'));
  159. // Wrap in a try/catch to prevent deadlock errors on busy servers
  160. try {
  161. $this->em->persist($download);
  162. $this->em->flush($download);
  163. } catch (\Exception $e) {
  164. if ($this->factory->getEnvironment() == 'dev') {
  165. throw $e;
  166. } else {
  167. error_log($e);
  168. }
  169. }
  170. $this->em->detach($download);
  171. }
  172. /**
  173. * Increase the download count
  174. *
  175. * @param $asset
  176. * @param int $increaseBy
  177. * @param bool|false $unique
  178. */
  179. public function upDownloadCount($asset, $increaseBy = 1, $unique = false)
  180. {
  181. $id = ($asset instanceof Asset) ? $asset->getId() : (int) $asset;
  182. $this->getRepository()->upDownloadCount($id, $increaseBy, $unique);
  183. }
  184. /**
  185. * @return \Mautic\AssetBundle\Entity\AssetRepository
  186. */
  187. public function getRepository()
  188. {
  189. return $this->em->getRepository('MauticAssetBundle:Asset');
  190. }
  191. /**
  192. * @return \Mautic\AssetBundle\Entity\DownloadRepository
  193. */
  194. public function getDownloadRepository()
  195. {
  196. return $this->em->getRepository('MauticAssetBundle:Download');
  197. }
  198. /**
  199. * @return string
  200. */
  201. public function getPermissionBase()
  202. {
  203. return 'asset:assets';
  204. }
  205. /**
  206. * @return string
  207. */
  208. public function getNameGetter()
  209. {
  210. return "getTitle";
  211. }
  212. /**
  213. * {@inheritdoc}
  214. *
  215. * @throws NotFoundHttpException
  216. */
  217. public function createForm($entity, $formFactory, $action = null, $options = array())
  218. {
  219. if (!$entity instanceof Asset) {
  220. throw new MethodNotAllowedHttpException(array('Asset'));
  221. }
  222. $params = (!empty($action)) ? array('action' => $action) : array();
  223. return $formFactory->create('asset', $entity, $params);
  224. }
  225. /**
  226. * Get a specific entity or generate a new one if id is empty
  227. *
  228. * @param $id
  229. * @return null|object
  230. */
  231. public function getEntity($id = null)
  232. {
  233. if ($id === null) {
  234. $entity = new Asset();
  235. } else {
  236. $entity = parent::getEntity($id);
  237. }
  238. return $entity;
  239. }
  240. /**
  241. * {@inheritdoc}
  242. *
  243. * @param $action
  244. * @param $event
  245. * @param $entity
  246. * @param $isNew
  247. * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
  248. */
  249. protected function dispatchEvent($action, &$entity, $isNew = false, Event $event = null)
  250. {
  251. if (!$entity instanceof Asset) {
  252. throw new MethodNotAllowedHttpException(array('Asset'));
  253. }
  254. switch ($action) {
  255. case "pre_save":
  256. $name = AssetEvents::ASSET_PRE_SAVE;
  257. break;
  258. case "post_save":
  259. $name = AssetEvents::ASSET_POST_SAVE;
  260. break;
  261. case "pre_delete":
  262. $name = AssetEvents::ASSET_PRE_DELETE;
  263. break;
  264. case "post_delete":
  265. $name = AssetEvents::ASSET_POST_DELETE;
  266. break;
  267. default:
  268. return null;
  269. }
  270. if ($this->dispatcher->hasListeners($name)) {
  271. if (empty($event)) {
  272. $event = new AssetEvent($entity, $isNew);
  273. $event->setEntityManager($this->em);
  274. }
  275. $this->dispatcher->dispatch($name, $event);
  276. return $event;
  277. } else {
  278. return null;
  279. }
  280. }
  281. /**
  282. * Get list of entities for autopopulate fields
  283. *
  284. * @param $type
  285. * @param $filter
  286. * @param $limit
  287. *
  288. * @return array
  289. */
  290. public function getLookupResults($type, $filter = '', $limit = 10)
  291. {
  292. $results = array();
  293. switch ($type) {
  294. case 'asset':
  295. $viewOther = $this->security->isGranted('asset:assets:viewother');
  296. $repo = $this->getRepository();
  297. $repo->setCurrentUser($this->factory->getUser());
  298. $results = $repo->getAssetList($filter, $limit, 0, $viewOther);
  299. break;
  300. case 'category':
  301. $results = $this->factory->getModel('category.category')->getRepository()->getCategoryList($filter, $limit, 0);
  302. break;
  303. }
  304. return $results;
  305. }
  306. /**
  307. * Generate url for an asset
  308. *
  309. * @param Asset $entity
  310. * @param bool $absolute
  311. * @param array $clickthrough
  312. *
  313. * @return string
  314. */
  315. public function generateUrl($entity, $absolute = true, $clickthrough = array())
  316. {
  317. $assetSlug = $entity->getId() . ':' . $entity->getAlias();
  318. $slugs = array(
  319. 'slug' => $assetSlug
  320. );
  321. return $this->buildUrl('mautic_asset_download', $slugs, $absolute, $clickthrough);
  322. }
  323. /**
  324. * Determine the max upload size based on PHP restrictions and config
  325. *
  326. * @param string $unit If '', determine the best unit based on the number
  327. * @param bool|false $humanReadable Return as a human readable filesize
  328. *
  329. * @return float
  330. */
  331. public function getMaxUploadSize($unit = 'M', $humanReadable = false)
  332. {
  333. $maxAssetSize = $this->factory->getParameter('max_size');
  334. $maxAssetSize = ($maxAssetSize == -1 || $maxAssetSize === 0) ? PHP_INT_MAX : Asset::convertSizeToBytes($maxAssetSize.'M');
  335. $maxPostSize = Asset::getIniValue('post_max_size');
  336. $maxUploadSize = Asset::getIniValue('upload_max_filesize');
  337. $memoryLimit = Asset::getIniValue('memory_limit');
  338. $maxAllowed = min(array_filter(array($maxAssetSize, $maxPostSize, $maxUploadSize, $memoryLimit)));
  339. if ($humanReadable) {
  340. $number = Asset::convertBytesToHumanReadable($maxAllowed);
  341. } else {
  342. list($number, $unit) = Asset::convertBytesToUnit($maxAllowed, $unit);
  343. }
  344. return $number;
  345. }
  346. /**
  347. * @param $assets
  348. *
  349. * @return int|string
  350. */
  351. public function getTotalFilesize($assets)
  352. {
  353. $firstAsset = is_array($assets) ? reset($assets) : false;
  354. if ($assets instanceof PersistentCollection || is_object($firstAsset)) {
  355. $assetIds = array();
  356. foreach ($assets as $asset) {
  357. $assetIds[] = $asset->getId();
  358. }
  359. $assets = $assetIds;
  360. }
  361. if (!is_array($assets)) {
  362. $assets = array($assets);
  363. }
  364. if (empty($assets)) {
  365. return 0;
  366. }
  367. $repo = $this->getRepository();
  368. $size = $repo->getAssetSize($assets);
  369. if ($size) {
  370. $size = Asset::convertBytesToHumanReadable($size);
  371. }
  372. return $size;
  373. }
  374. }