Teknik is a suite of services with attractive and functional interfaces. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Site.php 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik;
  10. use Exception;
  11. use Piwik\Plugins\SitesManager\API;
  12. /**
  13. * Provides access to individual [site entity](/guides/persistence-and-the-mysql-backend#websites-aka-sites) data
  14. * (including name, URL, etc.).
  15. *
  16. * **Data Cache**
  17. *
  18. * Site data can be cached in order to avoid performing too many queries.
  19. * If a method needs many site entities, it is more efficient to query all of what
  20. * you need beforehand via the **SitesManager** API, then cache it using {@link setSites()} or
  21. * {@link setSitesFromArray()}.
  22. *
  23. * Subsequent calls to `new Site($id)` will use the data in the cache instead of querying the database.
  24. *
  25. * ### Examples
  26. *
  27. * **Basic usage**
  28. *
  29. * $site = new Site($idSite);
  30. * $name = $site->getName();
  31. *
  32. * **Without allocation**
  33. *
  34. * $name = Site::getNameFor($idSite);
  35. *
  36. * @api
  37. */
  38. class Site
  39. {
  40. const DEFAULT_SITE_TYPE = "website";
  41. /**
  42. * @var int|null
  43. */
  44. protected $id = null;
  45. /**
  46. * @var array
  47. */
  48. protected static $infoSites = array();
  49. /**
  50. * Constructor.
  51. *
  52. * @param int $idsite The ID of the site we want data for.
  53. */
  54. public function __construct($idsite)
  55. {
  56. $this->id = (int)$idsite;
  57. if (!isset(self::$infoSites[$this->id])) {
  58. $site = API::getInstance()->getSiteFromId($this->id);
  59. self::setSite($this->id, $site);
  60. }
  61. }
  62. /**
  63. * Sets the cached site data with an array that associates site IDs with
  64. * individual site data.
  65. *
  66. * @param array $sites The array of sites data. Indexed by site ID. eg,
  67. *
  68. * array('1' => array('name' => 'Site 1', ...),
  69. * '2' => array('name' => 'Site 2', ...))`
  70. */
  71. public static function setSites($sites)
  72. {
  73. foreach($sites as $idsite => $site) {
  74. self::setSite($idsite, $site);
  75. }
  76. }
  77. /**
  78. * Sets a site information in memory (statically cached).
  79. *
  80. * Plugins can filter the website attributes before it is cached, eg. to change the website name,
  81. * creation date, etc.
  82. *
  83. * @param $idSite
  84. * @param $infoSite
  85. * @throws Exception if website or idsite is invalid
  86. */
  87. protected static function setSite($idSite, $infoSite)
  88. {
  89. if(empty($idSite) || empty($infoSite)) {
  90. throw new Exception("An unexpected website was found, check idSite in the request.");
  91. }
  92. /**
  93. * Triggered so plugins can modify website entities without modifying the database.
  94. *
  95. * This event should **not** be used to add data that is expensive to compute. If you
  96. * need to make HTTP requests or query the database for more information, this is not
  97. * the place to do it.
  98. *
  99. * **Example**
  100. *
  101. * Piwik::addAction('Site.setSite', function ($idSite, &$info) {
  102. * $info['name'] .= " (original)";
  103. * });
  104. *
  105. * @param int $idSite The ID of the website entity that will be modified.
  106. * @param array $infoSite The website entity. [Learn more.](/guides/persistence-and-the-mysql-backend#websites-aka-sites)
  107. */
  108. Piwik::postEvent('Site.setSite', array($idSite, &$infoSite));
  109. self::$infoSites[$idSite] = $infoSite;
  110. }
  111. /**
  112. * Sets the cached Site data with a non-associated array of site data.
  113. *
  114. * @param array $sites The array of sites data. eg,
  115. *
  116. * array(
  117. * array('idsite' => '1', 'name' => 'Site 1', ...),
  118. * array('idsite' => '2', 'name' => 'Site 2', ...),
  119. * )
  120. */
  121. public static function setSitesFromArray($sites)
  122. {
  123. foreach ($sites as $site) {
  124. self::setSite($site['idsite'], $site);
  125. }
  126. }
  127. /**
  128. * The Multisites reports displays the first calendar date as the earliest day available for all websites.
  129. * Also, today is the later "today" available across all timezones.
  130. * @param array $siteIds Array of IDs for each site being displayed.
  131. * @return Date[] of two Date instances. First is the min-date & the second
  132. * is the max date.
  133. * @ignore
  134. */
  135. public static function getMinMaxDateAcrossWebsites($siteIds)
  136. {
  137. $siteIds = self::getIdSitesFromIdSitesString($siteIds);
  138. $now = Date::now();
  139. $minDate = null;
  140. $maxDate = $now->subDay(1)->getTimestamp();
  141. foreach ($siteIds as $idsite) {
  142. // look for 'now' in the website's timezone
  143. $timezone = Site::getTimezoneFor($idsite);
  144. $date = Date::adjustForTimezone($now->getTimestamp(), $timezone);
  145. if ($date > $maxDate) {
  146. $maxDate = $date;
  147. }
  148. // look for the absolute minimum date
  149. $creationDate = Site::getCreationDateFor($idsite);
  150. $date = Date::adjustForTimezone(strtotime($creationDate), $timezone);
  151. if (is_null($minDate) || $date < $minDate) {
  152. $minDate = $date;
  153. }
  154. }
  155. return array(Date::factory($minDate), Date::factory($maxDate));
  156. }
  157. /**
  158. * Returns a string representation of the site this instance references.
  159. *
  160. * Useful for debugging.
  161. *
  162. * @return string
  163. */
  164. public function __toString()
  165. {
  166. return "site id=" . $this->getId() . ",
  167. name=" . $this->getName() . ",
  168. url = " . $this->getMainUrl() . ",
  169. IPs excluded = " . $this->getExcludedIps() . ",
  170. timezone = " . $this->getTimezone() . ",
  171. currency = " . $this->getCurrency() . ",
  172. creation date = " . $this->getCreationDate();
  173. }
  174. /**
  175. * Returns the name of the site.
  176. *
  177. * @return string
  178. * @throws Exception if data for the site cannot be found.
  179. */
  180. public function getName()
  181. {
  182. return $this->get('name');
  183. }
  184. /**
  185. * Returns the main url of the site.
  186. *
  187. * @return string
  188. * @throws Exception if data for the site cannot be found.
  189. */
  190. public function getMainUrl()
  191. {
  192. return $this->get('main_url');
  193. }
  194. /**
  195. * Returns the id of the site.
  196. *
  197. * @return int
  198. * @throws Exception if data for the site cannot be found.
  199. */
  200. public function getId()
  201. {
  202. return $this->id;
  203. }
  204. /**
  205. * Returns a site property by name.
  206. *
  207. * @param string $name Name of the property to return (eg, `'main_url'` or `'name'`).
  208. * @return mixed
  209. * @throws Exception
  210. */
  211. protected function get($name)
  212. {
  213. if (!isset(self::$infoSites[$this->id][$name])) {
  214. throw new Exception('The requested website id = ' . (int)$this->id . ' (or its property ' . $name . ') couldn\'t be found');
  215. }
  216. return self::$infoSites[$this->id][$name];
  217. }
  218. /**
  219. * Returns the website type (by default `"website"`, which means it is a single website).
  220. *
  221. * @return string
  222. */
  223. public function getType()
  224. {
  225. $type = $this->get('type');
  226. return $type;
  227. }
  228. /**
  229. * Returns the creation date of the site.
  230. *
  231. * @return Date
  232. * @throws Exception if data for the site cannot be found.
  233. */
  234. public function getCreationDate()
  235. {
  236. $date = $this->get('ts_created');
  237. return Date::factory($date);
  238. }
  239. /**
  240. * Returns the timezone of the size.
  241. *
  242. * @return string
  243. * @throws Exception if data for the site cannot be found.
  244. */
  245. public function getTimezone()
  246. {
  247. return $this->get('timezone');
  248. }
  249. /**
  250. * Returns the currency of the site.
  251. *
  252. * @return string
  253. * @throws Exception if data for the site cannot be found.
  254. */
  255. public function getCurrency()
  256. {
  257. return $this->get('currency');
  258. }
  259. /**
  260. * Returns the excluded ips of the site.
  261. *
  262. * @return string
  263. * @throws Exception if data for the site cannot be found.
  264. */
  265. public function getExcludedIps()
  266. {
  267. return $this->get('excluded_ips');
  268. }
  269. /**
  270. * Returns the excluded query parameters of the site.
  271. *
  272. * @return string
  273. * @throws Exception if data for the site cannot be found.
  274. */
  275. public function getExcludedQueryParameters()
  276. {
  277. return $this->get('excluded_parameters');
  278. }
  279. /**
  280. * Returns whether ecommerce is enabled for the site.
  281. *
  282. * @return bool
  283. * @throws Exception if data for the site cannot be found.
  284. */
  285. public function isEcommerceEnabled()
  286. {
  287. return $this->get('ecommerce') == 1;
  288. }
  289. /**
  290. * Returns the site search keyword query parameters for the site.
  291. *
  292. * @return string
  293. * @throws Exception if data for the site cannot be found.
  294. */
  295. public function getSearchKeywordParameters()
  296. {
  297. return $this->get('sitesearch_keyword_parameters');
  298. }
  299. /**
  300. * Returns the site search category query parameters for the site.
  301. *
  302. * @return string
  303. * @throws Exception if data for the site cannot be found.
  304. */
  305. public function getSearchCategoryParameters()
  306. {
  307. return $this->get('sitesearch_category_parameters');
  308. }
  309. /**
  310. * Returns whether Site Search Tracking is enabled for the site.
  311. *
  312. * @return bool
  313. * @throws Exception if data for the site cannot be found.
  314. */
  315. public function isSiteSearchEnabled()
  316. {
  317. return $this->get('sitesearch') == 1;
  318. }
  319. /**
  320. * Checks the given string for valid site IDs and returns them as an array.
  321. *
  322. * @param string|array $ids Comma separated idSite list, eg, `'1,2,3,4'` or an array of IDs, eg,
  323. * `array(1, 2, 3, 4)`.
  324. * @param bool|string $_restrictSitesToLogin Implementation detail. Used only when running as a scheduled task.
  325. * @return array An array of valid, unique integers.
  326. */
  327. public static function getIdSitesFromIdSitesString($ids, $_restrictSitesToLogin = false)
  328. {
  329. if ($ids === 'all') {
  330. return API::getInstance()->getSitesIdWithAtLeastViewAccess($_restrictSitesToLogin);
  331. }
  332. if(is_bool($ids)) {
  333. return array();
  334. }
  335. if (!is_array($ids)) {
  336. $ids = explode(',', $ids);
  337. }
  338. $validIds = array();
  339. foreach ($ids as $id) {
  340. $id = trim($id);
  341. if (!empty($id) && is_numeric($id) && $id > 0) {
  342. $validIds[] = $id;
  343. }
  344. }
  345. $validIds = array_filter($validIds);
  346. $validIds = array_unique($validIds);
  347. return $validIds;
  348. }
  349. /**
  350. * Clears the site data cache.
  351. *
  352. * See also {@link setSites()} and {@link setSitesFromArray()}.
  353. */
  354. public static function clearCache()
  355. {
  356. self::$infoSites = array();
  357. }
  358. /**
  359. * Utility function. Returns the value of the specified field for the
  360. * site with the specified ID.
  361. *
  362. * @param int $idsite The ID of the site whose data is being accessed.
  363. * @param bool|string $field The name of the field to get.
  364. * @return array|string
  365. */
  366. protected static function getFor($idsite, $field = false)
  367. {
  368. $idsite = (int)$idsite;
  369. if (!isset(self::$infoSites[$idsite])) {
  370. $site = API::getInstance()->getSiteFromId($idsite);
  371. self::setSite($idsite, $site);
  372. }
  373. if($field) {
  374. return self::$infoSites[$idsite][$field];
  375. }
  376. return self::$infoSites[$idsite];
  377. }
  378. /**
  379. * Returns all websites pre-cached
  380. *
  381. * @ignore
  382. */
  383. public static function getSites()
  384. {
  385. return self::$infoSites;
  386. }
  387. /**
  388. * @ignore
  389. */
  390. public static function getSite($id)
  391. {
  392. return self::getFor($id);
  393. }
  394. /**
  395. * Returns the name of the site with the specified ID.
  396. *
  397. * @param int $idsite The site ID.
  398. * @return string
  399. */
  400. public static function getNameFor($idsite)
  401. {
  402. return self::getFor($idsite, 'name');
  403. }
  404. /**
  405. * Returns the group of the site with the specified ID.
  406. *
  407. * @param int $idsite The site ID.
  408. * @return string
  409. */
  410. public static function getGroupFor($idsite)
  411. {
  412. return self::getFor($idsite, 'group');
  413. }
  414. /**
  415. * Returns the timezone of the site with the specified ID.
  416. *
  417. * @param int $idsite The site ID.
  418. * @return string
  419. */
  420. public static function getTimezoneFor($idsite)
  421. {
  422. return self::getFor($idsite, 'timezone');
  423. }
  424. /**
  425. * Returns the type of the site with the specified ID.
  426. *
  427. * @param $idsite
  428. * @return string
  429. */
  430. public static function getTypeFor($idsite)
  431. {
  432. return self::getFor($idsite, 'type');
  433. }
  434. /**
  435. * Returns the creation date of the site with the specified ID.
  436. *
  437. * @param int $idsite The site ID.
  438. * @return string
  439. */
  440. public static function getCreationDateFor($idsite)
  441. {
  442. return self::getFor($idsite, 'ts_created');
  443. }
  444. /**
  445. * Returns the url for the site with the specified ID.
  446. *
  447. * @param int $idsite The site ID.
  448. * @return string
  449. */
  450. public static function getMainUrlFor($idsite)
  451. {
  452. return self::getFor($idsite, 'main_url');
  453. }
  454. /**
  455. * Returns whether the site with the specified ID is ecommerce enabled or not.
  456. *
  457. * @param int $idsite The site ID.
  458. * @return string
  459. */
  460. public static function isEcommerceEnabledFor($idsite)
  461. {
  462. return self::getFor($idsite, 'ecommerce') == 1;
  463. }
  464. /**
  465. * Returns whether the site with the specified ID is Site Search enabled.
  466. *
  467. * @param int $idsite The site ID.
  468. * @return string
  469. */
  470. public static function isSiteSearchEnabledFor($idsite)
  471. {
  472. return self::getFor($idsite, 'sitesearch') == 1;
  473. }
  474. /**
  475. * Returns the currency of the site with the specified ID.
  476. *
  477. * @param int $idsite The site ID.
  478. * @return string
  479. */
  480. public static function getCurrencyFor($idsite)
  481. {
  482. return self::getFor($idsite, 'currency');
  483. }
  484. /**
  485. * Returns the excluded IP addresses of the site with the specified ID.
  486. *
  487. * @param int $idsite The site ID.
  488. * @return string
  489. */
  490. public static function getExcludedIpsFor($idsite)
  491. {
  492. return self::getFor($idsite, 'excluded_ips');
  493. }
  494. /**
  495. * Returns the excluded query parameters for the site with the specified ID.
  496. *
  497. * @param int $idsite The site ID.
  498. * @return string
  499. */
  500. public static function getExcludedQueryParametersFor($idsite)
  501. {
  502. return self::getFor($idsite, 'excluded_parameters');
  503. }
  504. }