PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/titania/includes/objects/revision.php

http://github.com/phpbb/customisation-db
PHP | 613 lines | 412 code | 88 blank | 113 comment | 73 complexity | a830ed207bce60b1d0291a89f8b4c795 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package Titania
  5. * @copyright (c) 2008 phpBB Customisation Database Team
  6. * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License, version 2
  7. *
  8. */
  9. /**
  10. * @ignore
  11. */
  12. if (!defined('IN_TITANIA'))
  13. {
  14. exit;
  15. }
  16. if (!class_exists('titania_database_object'))
  17. {
  18. require TITANIA_ROOT . 'includes/core/object_database.' . PHP_EXT;
  19. }
  20. /**
  21. * Class to titania revision.
  22. * @package Titania
  23. *
  24. * @todo Create revision_status field to store whether this revision is new, validated, or pulled (for security or other reasons)
  25. */
  26. class titania_revision extends titania_database_object
  27. {
  28. /**
  29. * SQL Table
  30. *
  31. * @var string
  32. */
  33. protected $sql_table = TITANIA_REVISIONS_TABLE;
  34. /**
  35. * SQL identifier field
  36. *
  37. * @var string
  38. */
  39. protected $sql_id_field = 'revision_id';
  40. /**
  41. * Contribution object
  42. *
  43. * @var object
  44. */
  45. public $contrib = false;
  46. /**
  47. * phpBB versions, translations
  48. *
  49. * @var mixed
  50. */
  51. public $phpbb_versions = array();
  52. public $translations = array();
  53. public function __construct($contrib, $revision_id = false)
  54. {
  55. // Configure object properties
  56. $this->object_config = array_merge($this->object_config, array(
  57. 'revision_id' => array('default' => 0),
  58. 'contrib_id' => array('default' => 0),
  59. 'revision_status' => array('default' => TITANIA_REVISION_NEW),
  60. 'attachment_id' => array('default' => 0),
  61. 'revision_name' => array('default' => '', 'max' => 255),
  62. 'revision_time' => array('default' => (int) titania::$time),
  63. 'validation_date' => array('default' => 0),
  64. 'revision_version' => array('default' => ''),
  65. 'install_time' => array('default' => 0),
  66. 'install_level' => array('default' => 0),
  67. 'revision_submitted' => array('default' => false), // False if it is still in the process of being submitted/verified; True if submission has finished
  68. 'revision_queue_id' => array('default' => 0),
  69. 'revision_license' => array('default' => ''),
  70. 'revision_clr_options' => array('default' => ''),
  71. ));
  72. if ($contrib)
  73. {
  74. $this->contrib = $contrib;
  75. $this->contrib_id = $this->contrib->contrib_id;
  76. }
  77. $this->revision_id = $revision_id;
  78. // Hooks
  79. titania::$hook->call_hook_ref(array(__CLASS__, __FUNCTION__), $this);
  80. }
  81. /**
  82. * Load the phpBB branches we've selected for this revision
  83. * Stored in $this->phpbb_versions
  84. */
  85. public function load_phpbb_versions()
  86. {
  87. $sql = 'SELECT * FROM ' . TITANIA_REVISIONS_PHPBB_TABLE . '
  88. WHERE revision_id = ' . (int) $this->revision_id;
  89. $result = phpbb::$db->sql_query($sql);
  90. while ($row = phpbb::$db->sql_fetchrow($result))
  91. {
  92. $this->phpbb_versions[] = $row;
  93. }
  94. phpbb::$db->sql_freeresult($result);
  95. }
  96. /**
  97. * Load the Translations for this revision
  98. * Stored in $this->translations
  99. */
  100. public function load_translations()
  101. {
  102. $sql = 'SELECT * FROM ' . TITANIA_ATTACHMENTS_TABLE . '
  103. WHERE object_type = ' . TITANIA_TRANSLATION . '
  104. AND object_id = ' . $this->revision_id;
  105. $result = phpbb::$db->sql_query($sql);
  106. while ($row = phpbb::$db->sql_fetchrow($result))
  107. {
  108. $this->translations[] = $row;
  109. }
  110. phpbb::$db->sql_freeresult($result);
  111. }
  112. /**
  113. * Get the branches we've selected for this revision (load them first!)
  114. */
  115. public function get_selected_branches()
  116. {
  117. $branches = array();
  118. foreach ($this->phpbb_versions as $row)
  119. {
  120. $branches[] = $row['phpbb_version_branch'];
  121. }
  122. return array_unique($branches);
  123. }
  124. public function display($tpl_block = 'revisions', $show_queue = false, $all_versions = false)
  125. {
  126. titania::_include('functions_display', 'order_phpbb_version_list_from_db');
  127. $ordered_phpbb_versions = order_phpbb_version_list_from_db($this->phpbb_versions, $all_versions);
  128. // Get rid of the day of the week if it exists in the dateformat
  129. $old_date_format = phpbb::$user->date_format;
  130. phpbb::$user->date_format = str_replace('D ', '', phpbb::$user->date_format);
  131. $install_time = false;
  132. if ($this->install_time > 0)
  133. {
  134. if ($this->install_time < 60)
  135. {
  136. $install_time = phpbb::$user->lang['INSTALL_LESS_THAN_1_MINUTE'];
  137. }
  138. else
  139. {
  140. $install_time = phpbb::$user->lang('INSTALL_MINUTES', (int) ($this->install_time / 60));
  141. }
  142. }
  143. // ColorizeIt stuff
  144. $url_colorizeit = '';
  145. if($this->revision_status == TITANIA_REVISION_APPROVED && strlen(titania::$config->colorizeit) && $this->contrib && $this->contrib->has_colorizeit())
  146. {
  147. $url_colorizeit = 'http://' . titania::$config->colorizeit_url . '/custom/' . titania::$config->colorizeit . '.html?id=' . $this->attachment_id . '&amp;sample=' . $this->contrib->clr_sample['attachment_id'];
  148. }
  149. phpbb::$template->assign_block_vars($tpl_block, array(
  150. 'REVISION_ID' => $this->revision_id,
  151. 'CREATED' => phpbb::$user->format_date($this->revision_time),
  152. 'NAME' => ($this->revision_name) ? censor_text($this->revision_name) : (($this->contrib) ? $this->contrib->contrib_name . ' ' . $this->revision_version : ''),
  153. 'VERSION' => $this->revision_version,
  154. 'VALIDATED_DATE' => ($this->validation_date) ? phpbb::$user->format_date($this->validation_date) : phpbb::$user->lang['NOT_VALIDATED'],
  155. 'REVISION_QUEUE' => ($show_queue && $this->revision_queue_id) ? titania_url::build_url('manage/queue', array('q' => $this->revision_queue_id)) : '',
  156. 'PHPBB_VERSION' => (sizeof($ordered_phpbb_versions) == 1) ? $ordered_phpbb_versions[0] : '',
  157. 'REVISION_LICENSE' => ($this->revision_license) ? censor_text($this->revision_license) : (($this->contrib && sizeof(titania_types::$types[$this->contrib->contrib_type]->license_options)) ? phpbb::$user->lang['UNKNOWN'] : ''),
  158. 'INSTALL_TIME' => $install_time,
  159. 'INSTALL_LEVEL' => ($this->install_level > 0) ? phpbb::$user->lang['INSTALL_LEVEL_' . $this->install_level] : '',
  160. 'DOWNLOADS' => isset($this->download_count) ? $this->download_count : 0,
  161. 'U_DOWNLOAD' => $this->get_url(),
  162. 'U_COLORIZEIT' => $url_colorizeit,
  163. 'U_EDIT' => ($this->contrib && ($this->contrib->is_author || $this->contrib->is_active_coauthor || titania_types::$types[$this->contrib->contrib_type]->acl_get('moderate'))) ? $this->contrib->get_url('revision_edit', array('revision' => $this->revision_id)) : '',
  164. 'U_VIEW_INSTALL' => (titania_types::$types[$this->contrib->contrib_type]->display_install_file && file_exists(titania::$config->modx_storage_path . $this->revision_id)) ? titania_url::build_url('view-install', array('id' => $this->revision_id)) : '',
  165. 'S_USE_QUEUE' => (titania::$config->use_queue && titania_types::$types[$this->contrib->contrib_type]->use_queue) ? true : false,
  166. 'S_NEW' => ($this->revision_status == TITANIA_REVISION_NEW) ? true : false,
  167. 'S_APPROVED' => ($this->revision_status == TITANIA_REVISION_APPROVED) ? true : false,
  168. 'S_DENIED' => ($this->revision_status == TITANIA_REVISION_DENIED) ? true : false,
  169. 'S_PULLED_SECURITY' => ($this->revision_status == TITANIA_REVISION_PULLED_SECURITY) ? true : false,
  170. 'S_PULLED_OTHER' => ($this->revision_status == TITANIA_REVISION_PULLED_OTHER) ? true : false,
  171. 'S_REPACKED' => ($this->revision_status == TITANIA_REVISION_REPACKED) ? true : false,
  172. 'S_RESUBMITTED' => ($this->revision_status == TITANIA_REVISION_RESUBMITTED) ? true : false,
  173. ));
  174. phpbb::$user->date_format = $old_date_format;
  175. // Output phpBB versions
  176. foreach ($ordered_phpbb_versions as $version)
  177. {
  178. phpbb::$template->assign_block_vars($tpl_block . '.phpbb_versions', array(
  179. 'VERSION' => $version,
  180. ));
  181. }
  182. // Output translations
  183. if (sizeof($this->translations))
  184. {
  185. $translations = new titania_attachment(TITANIA_TRANSLATION, $this->revision_id);
  186. $translations->store_attachments($this->translations);
  187. foreach ($translations->parse_attachments($message = false) as $attachment)
  188. {
  189. phpbb::$template->assign_block_vars($tpl_block . '.translations', array(
  190. 'DISPLAY_ATTACHMENT' => $attachment,
  191. ));
  192. }
  193. }
  194. phpbb::$template->assign_var('ICON_EDIT', '<img src="' . titania::$images_path . 'icon_edit.gif" alt="' . phpbb::$user->lang['EDIT'] . '" title="' . phpbb::$user->lang['EDIT'] . '" />');
  195. // Hooks
  196. titania::$hook->call_hook(array(__CLASS__, __FUNCTION__), $this, $tpl_block);
  197. }
  198. /**
  199. * Handle some stuff we need when submitting a revision
  200. */
  201. public function submit()
  202. {
  203. if (!$this->revision_id)
  204. {
  205. // Update the contrib_last_update if required here
  206. if (!titania::$config->require_validation || !titania_types::$types[$this->contrib->contrib_type]->require_validation)
  207. {
  208. $this->contrib->contrib_last_update = titania::$time;
  209. $sql_ary = array(
  210. 'contrib_last_update' => $this->contrib->contrib_last_update,
  211. );
  212. $sql = 'UPDATE ' . TITANIA_CONTRIBS_TABLE . '
  213. SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . '
  214. WHERE contrib_id = ' . $this->contrib_id;
  215. phpbb::$db->sql_query($sql);
  216. // Subscriptions
  217. $email_vars = array(
  218. 'NAME' => $this->contrib->contrib_name,
  219. 'U_VIEW' => $this->contrib->get_url(),
  220. );
  221. titania_subscriptions::send_notifications(TITANIA_CONTRIB, $this->contrib_id, 'subscribe_notify.txt', $email_vars);
  222. }
  223. }
  224. else if (sizeof($this->phpbb_versions))
  225. {
  226. $sql = 'DELETE FROM ' . TITANIA_REVISIONS_PHPBB_TABLE . '
  227. WHERE revision_id = ' . (int) $this->revision_id;
  228. phpbb::$db->sql_query($sql);
  229. }
  230. parent::submit();
  231. // Add phpBB versions supported
  232. if (sizeof($this->phpbb_versions))
  233. {
  234. $versions = titania::$cache->get_phpbb_versions();
  235. $sql_ary = array();
  236. foreach ($this->phpbb_versions as $row)
  237. {
  238. if (!is_array($row)) // Accept from user input
  239. {
  240. $row = array('phpbb_version_branch' => (int) $row);
  241. }
  242. if (!isset($row['phpbb_version_branch']) || !isset(titania::$config->phpbb_versions[$row['phpbb_version_branch']]))
  243. {
  244. continue;
  245. }
  246. // OMG, it's not in our cache!
  247. if (!isset($versions[$row['phpbb_version_branch'] . titania::$config->phpbb_versions[$row['phpbb_version_branch']]]))
  248. {
  249. titania::$cache->destroy('_titania_phpbb_versions');
  250. }
  251. $sql_ary[] = array(
  252. 'revision_id' => $this->revision_id,
  253. 'contrib_id' => $this->contrib_id,
  254. 'revision_validated' => ($this->revision_status == TITANIA_REVISION_APPROVED) ? true : false,
  255. 'phpbb_version_branch' => $row['phpbb_version_branch'],
  256. 'phpbb_version_revision' => get_real_revision_version(((isset($row['phpbb_version_revision'])) ? $row['phpbb_version_revision'] : titania::$config->phpbb_versions[$row['phpbb_version_branch']]['latest_revision'])),
  257. );
  258. }
  259. if (sizeof($sql_ary))
  260. {
  261. phpbb::$db->sql_multi_insert(TITANIA_REVISIONS_PHPBB_TABLE, $sql_ary);
  262. }
  263. }
  264. // Update the release topic
  265. if ($this->revision_status == TITANIA_REVISION_APPROVED)
  266. {
  267. $this->contrib->update_release_topic();
  268. }
  269. // Hooks
  270. titania::$hook->call_hook_ref(array(__CLASS__, __FUNCTION__), $this);
  271. }
  272. /**
  273. * Change the status of this revision
  274. *
  275. * @param int $new_status
  276. */
  277. public function change_status($new_status)
  278. {
  279. $new_status = (int) $new_status;
  280. $old_status = $this->revision_status;
  281. if ($old_status == $new_status)
  282. {
  283. return;
  284. }
  285. $this->revision_status = $new_status;
  286. $sql_ary = array(
  287. 'revision_status' => $this->revision_status,
  288. );
  289. switch ($old_status)
  290. {
  291. case TITANIA_REVISION_APPROVED :
  292. // If there are no approved revisions left we will need to reset the contribution status
  293. $sql = 'SELECT COUNT(revision_id) AS cnt FROM ' . TITANIA_REVISIONS_TABLE . '
  294. WHERE revision_status = ' . TITANIA_REVISION_APPROVED . '
  295. AND contrib_id = ' . $this->contrib_id . '
  296. AND revision_id <> ' . $this->revision_id;
  297. phpbb::$db->sql_query($sql);
  298. $cnt = phpbb::$db->sql_fetchfield('cnt');
  299. if (!$cnt)
  300. {
  301. if (!$this->contrib)
  302. {
  303. $this->contrib = contribs_overlord::get_contrib_object($this->contrib_id, true);
  304. }
  305. if (in_array($this->contrib->contrib_status, array(TITANIA_CONTRIB_APPROVED, TITANIA_CONTRIB_DOWNLOAD_DISABLED)))
  306. {
  307. $this->contrib->change_status(TITANIA_CONTRIB_NEW);
  308. }
  309. }
  310. break;
  311. }
  312. switch ($new_status)
  313. {
  314. case TITANIA_REVISION_APPROVED :
  315. // If approving this revision and the contribution is set to new, approve the contribution
  316. if (!$this->contrib)
  317. {
  318. $this->contrib = contribs_overlord::get_contrib_object($this->contrib_id, true);
  319. }
  320. if (in_array($this->contrib->contrib_status, array(TITANIA_CONTRIB_NEW)))
  321. {
  322. $this->contrib->change_status(TITANIA_CONTRIB_APPROVED);
  323. }
  324. // Update the revisions phpbb version table
  325. $sql = 'UPDATE ' . TITANIA_REVISIONS_PHPBB_TABLE . '
  326. SET revision_validated = 1
  327. WHERE revision_id = ' . (int) $this->revision_id;
  328. phpbb::$db->sql_query($sql);
  329. $sql_ary['validation_date'] = titania::$time;
  330. // Update the contributions table if this is the newest validated revision
  331. $sql = 'SELECT revision_id FROM ' . $this->sql_table . '
  332. WHERE revision_status = ' . TITANIA_REVISION_APPROVED . '
  333. AND contrib_id = ' . $this->contrib_id . '
  334. ORDER BY revision_id DESC';
  335. phpbb::$db->sql_query_limit($sql, 1);
  336. $newest_revision_id = phpbb::$db->sql_fetchfield('revision_id');
  337. phpbb::$db->sql_freeresult();
  338. if ($newest_revision_id && (int) $newest_revision_id < $this->revision_id)
  339. {
  340. $sql = 'UPDATE ' . TITANIA_CONTRIBS_TABLE . '
  341. SET contrib_last_update = ' . titania::$time . '
  342. WHERE contrib_id = ' . (int) $this->contrib_id;
  343. phpbb::$db->sql_query($sql);
  344. }
  345. break;
  346. default :
  347. // Update the revisions phpbb version table
  348. $sql = 'UPDATE ' . TITANIA_REVISIONS_PHPBB_TABLE . '
  349. SET revision_validated = 0
  350. WHERE revision_id = ' . (int) $this->revision_id;
  351. phpbb::$db->sql_query($sql);
  352. $sql_ary['validation_date'] = 0;
  353. break;
  354. }
  355. $sql = 'UPDATE ' . $this->sql_table . '
  356. SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . '
  357. WHERE revision_id = ' . $this->revision_id;
  358. phpbb::$db->sql_query($sql);
  359. // Update the release topic
  360. if ($this->revision_status == TITANIA_REVISION_APPROVED)
  361. {
  362. $this->contrib->update_release_topic();
  363. }
  364. }
  365. /**
  366. * Repack a revision
  367. *
  368. * @param titania_revision $old_revision titania_revision object
  369. */
  370. public function repack($old_revision)
  371. {
  372. if (!$this->revision_id)
  373. {
  374. throw new exception('Submit the revision before repacking');
  375. }
  376. titania::add_lang('manage');
  377. // Get the old and new queue objects
  378. $old_queue = $old_revision->get_queue();
  379. $queue = $this->get_queue();
  380. if ($old_queue === false)
  381. {
  382. throw new exception('Old queue missing. Revision ID: ' . $old_revision->revision_id);
  383. }
  384. // Reply to the queue topic to say that it's been repacked and have the old mpv/automod results listed in it as well
  385. $repack_message = phpbb::$user->lang['REVISION_REPACKED'] . "\n\n";
  386. // Add the MPV results
  387. if ($queue->mpv_results)
  388. {
  389. $repack_message .= '[quote=&quot;' . phpbb::$user->lang['VALIDATION_MPV'] . '&quot;]' . $queue->mpv_results . "[/quote]\n";
  390. }
  391. // Add the Automod results
  392. if ($queue->automod_results)
  393. {
  394. $repack_message .= '[quote=&quot;' . phpbb::$user->lang['VALIDATION_AUTOMOD'] . '&quot;]' . $queue->automod_results . "[/quote]\n";
  395. }
  396. // Reply
  397. $old_queue->topic_reply($repack_message);
  398. // Update the old queue with the new results
  399. $old_queue->revision_id = $queue->revision_id;
  400. $old_queue->submit();
  401. // Delete the new queue we made for this revision
  402. $queue->delete();
  403. // Unlink the old queue_id from the old revision and set it to repacked
  404. $old_revision->change_status(TITANIA_REVISION_REPACKED);
  405. $old_revision->revision_queue_id = 0;
  406. $old_revision->submit();
  407. // Update the queue_id for this revision to point to the old queue_id
  408. $this->revision_queue_id = $old_queue->queue_id;
  409. $this->submit();
  410. // Move any translations
  411. $sql = 'UPDATE ' . TITANIA_ATTACHMENTS_TABLE . '
  412. SET object_id = ' . $this->revision_id . '
  413. WHERE object_type = ' . TITANIA_TRANSLATION . '
  414. AND object_id = ' . $old_revision->revision_id;
  415. phpbb::$db->sql_query($sql);
  416. // Hooks
  417. titania::$hook->call_hook_ref(array(__CLASS__, __FUNCTION__), $this);
  418. }
  419. public function delete()
  420. {
  421. // Hooks
  422. titania::$hook->call_hook_ref(array(__CLASS__, __FUNCTION__), $this);
  423. // Delete the queue item
  424. $queue = $this->get_queue();
  425. if ($queue !== false)
  426. {
  427. $queue->delete();
  428. }
  429. // Delete the attachment
  430. $attachment = new titania_attachment(TITANIA_CONTRIB);
  431. $attachment->attachment_id = $this->attachment_id;
  432. $attachment->load();
  433. $attachment->delete();
  434. // Delete translations
  435. // $translations = new titania_attachment(TITANIA_TRANSLATION, $this->revision_id);
  436. // $attachment->delete_all();
  437. // Self-destruct
  438. parent::delete();
  439. }
  440. /**
  441. * Update/create the queue entry for this revision
  442. */
  443. public function update_queue()
  444. {
  445. // Create the queue entry if required, else update it
  446. if (titania::$config->use_queue && titania_types::$types[$this->contrib->contrib_type]->use_queue)
  447. {
  448. $queue = $this->get_queue();
  449. // Only create the queue for revisions set as new
  450. if ($queue === false && $this->revision_status == TITANIA_REVISION_NEW)
  451. {
  452. $queue = new titania_queue;
  453. }
  454. // If we have to create or update one...
  455. if ($queue !== false)
  456. {
  457. $queue->__set_array(array(
  458. 'revision_id' => $this->revision_id,
  459. 'contrib_id' => $this->contrib_id,
  460. 'contrib_name_clean' => $this->contrib->contrib_name_clean,
  461. ));
  462. // Set the queue status to new if it's submitted and the queue status is set to hide it
  463. if ($this->revision_submitted && $queue->queue_status == TITANIA_QUEUE_HIDE)
  464. {
  465. // Only set the queue as new if there are not any newer revisions in the queue
  466. $sql = 'SELECT queue_id FROM ' . TITANIA_QUEUE_TABLE . '
  467. WHERE contrib_id = ' . (int) $this->contrib_id . '
  468. AND revision_id > ' . $this->revision_id;
  469. $result = phpbb::$db->sql_query($sql);
  470. if(!($row = phpbb::$db->sql_fetchrow($result)))
  471. {
  472. $queue->queue_status = TITANIA_QUEUE_NEW;
  473. }
  474. }
  475. $queue->submit();
  476. // Set the revision queue id
  477. $this->revision_queue_id = $queue->queue_id;
  478. parent::submit();
  479. if ($this->revision_submitted)
  480. {
  481. // Change the status on any old revisions that were in the queue and marked as New to repacked
  482. $sql = 'SELECT * FROM ' . TITANIA_QUEUE_TABLE . '
  483. WHERE contrib_id = ' . (int) $this->contrib_id . '
  484. AND revision_id < ' . $this->revision_id . '
  485. AND queue_status = ' . TITANIA_QUEUE_NEW;
  486. $result = phpbb::$db->sql_query($sql);
  487. while ($row = phpbb::$db->sql_fetchrow($result))
  488. {
  489. $queue = new titania_queue;
  490. $queue->__set_array($row);
  491. $queue->close(TITANIA_REVISION_RESUBMITTED);
  492. unset($queue);
  493. }
  494. phpbb::$db->sql_freeresult($result);
  495. }
  496. }
  497. }
  498. }
  499. /**
  500. * Get the queue object for this revision
  501. */
  502. public function get_queue()
  503. {
  504. $sql = 'SELECT * FROM ' . TITANIA_QUEUE_TABLE . '
  505. WHERE contrib_id = ' . $this->contrib_id . '
  506. AND revision_id = ' . $this->revision_id;
  507. $result = phpbb::$db->sql_query($sql);
  508. $row = phpbb::$db->sql_fetchrow($result);
  509. phpbb::$db->sql_freeresult($result);
  510. if ($row)
  511. {
  512. $queue = new titania_queue;
  513. $queue->__set_array($row);
  514. return $queue;
  515. }
  516. return false;
  517. }
  518. /**
  519. * Download URL
  520. */
  521. public function get_url()
  522. {
  523. return titania_url::build_url('download', array('id' => $this->attachment_id));
  524. }
  525. }