PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/ext.tag_sync.php

https://github.com/amphibian/ext.tag_sync.ee_addon
PHP | 425 lines | 297 code | 78 blank | 50 comment | 27 complexity | db525ff62d036fc1586c9c48b4a1bc6b MD5 | raw file
  1. <?php
  2. if(!defined('EXT'))
  3. {
  4. exit('Invalid file request');
  5. }
  6. class Tag_sync
  7. {
  8. var $settings = array();
  9. var $name = 'Tag Synchronizer';
  10. var $version = '1.0.5';
  11. var $description = 'Synchronize Solspace Tag tags to a custom field when entries are publish or updated, or all at once.';
  12. var $settings_exist = 'y';
  13. var $docs_url = 'http://github.com/amphibian/ext.tag_sync.ee_addon';
  14. var $batch_size = 1000;
  15. // -------------------------------
  16. // Constructor - Extensions use this for settings
  17. // -------------------------------
  18. function Tag_sync($settings='')
  19. {
  20. $this->settings = $settings;
  21. }
  22. // END
  23. // --------------------------------
  24. // Settings
  25. // --------------------------------
  26. function settings_form($current)
  27. {
  28. global $DB, $DSP, $IN, $LANG, $PREFS;
  29. // Synchronize all tags to a specific weblog's custom field
  30. if(isset($_GET['sync_weblog']) && !empty($current['weblog_id_'.$_GET['sync_weblog']]))
  31. {
  32. $sync_weblog = $_GET['sync_weblog'];
  33. $custom_field = $current['weblog_id_'.$sync_weblog];
  34. $current_batch = (isset($_GET['batch'])) ? $_GET['batch'] : 1;
  35. // Get count of entry IDs in this weblog which have tags
  36. $sql = "SELECT COUNT(DISTINCT entry_id) as count FROM exp_tag_entries WHERE weblog_id = ".$DB->escape_str($sync_weblog);
  37. $count = $DB->query($sql);
  38. if($count->row['count'] > 0)
  39. {
  40. $batches = ceil($count->row['count'] / $this->batch_size);
  41. $offset = ($current_batch - 1) * $this->batch_size;
  42. // Get the current batch of tagged entries to sync
  43. $sql = "SELECT DISTINCT entry_id FROM exp_tag_entries
  44. WHERE weblog_id = ".$DB->escape_str($sync_weblog)."
  45. ORDER BY entry_id ASC LIMIT $offset, ".$this->batch_size;
  46. $entries = $DB->query($sql);
  47. $entry_ids = array();
  48. foreach($entries->result as $result)
  49. {
  50. $entry_ids[] = $result['entry_id'];
  51. }
  52. // Get all tags for this batch's entry_ids
  53. $sql = "SELECT DISTINCT t.tag_name, e.entry_id FROM exp_tag_entries AS e
  54. LEFT JOIN exp_tag_tags AS t ON e.tag_id = t.tag_id
  55. WHERE e.entry_id IN('".implode("','", $DB->escape_str($entry_ids))."')
  56. ORDER BY e.entry_id ASC";
  57. $get_tags = $DB->query($sql);
  58. if($get_tags->num_rows > 0)
  59. {
  60. // Create an array with each entry_id as a key,
  61. // and an array of its tags as a value
  62. $tags = array();
  63. foreach($get_tags->result as $tag)
  64. {
  65. $tags[$tag['entry_id']][] = $tag['tag_name'];
  66. }
  67. // Build and run our update statement
  68. $sql = "UPDATE exp_weblog_data SET `field_id_".ceil($custom_field)."` = CASE entry_id ";
  69. foreach($tags as $entry_id => $tag)
  70. {
  71. $sql .= "WHEN ".$entry_id." THEN '".$DB->escape_str(implode(',', $tag))."' ";
  72. }
  73. $sql .= "END WHERE entry_id IN('".implode("','", $DB->escape_str($entry_ids))."')";
  74. $DB->query($sql);
  75. if($DB->affected_rows == 0)
  76. {
  77. // Everything was already in sync ('N Sync?)
  78. $message = $DSP->qspan('text', $LANG->line('nothing_to_sync'));
  79. }
  80. else
  81. {
  82. // We had updates
  83. $message = $DSP->span('text');
  84. $message .= $DB->affected_rows.' ';
  85. $message .= ($DB->affected_rows == 1) ? $LANG->line('entry') : $LANG->line('entries');
  86. $message .= ' '.$LANG->line('synced_in_batch');
  87. $message .= $DSP->span_c();
  88. }
  89. }
  90. else
  91. {
  92. // None of the entries had tags - kinda redundant,
  93. // as we were only selecting entries with tags, but still...
  94. $message = $DSP->qspan('text', $LANG->line('nothing_to_sync'));
  95. }
  96. if($current_batch < $batches)
  97. {
  98. // We have more batches to run
  99. $message .= ' '.$DSP->anchor(
  100. BASE.AMP.'C=admin'.
  101. AMP.'M=utilities'.
  102. AMP.'P=extension_settings'.
  103. AMP.'name=tag_sync'.
  104. AMP.'sync_weblog='.$sync_weblog.
  105. AMP.'batch='.($current_batch + 1),
  106. $LANG->line('run_batch').' '.($current_batch + 1).' '.$LANG->line('of').' '.$batches.'.',
  107. 'class="bold"'
  108. );
  109. }
  110. else
  111. {
  112. // We're all done!
  113. $message .= $DSP->qspan('success', ' '.$LANG->line('sync_complete'));
  114. }
  115. }
  116. else
  117. {
  118. // The weblog has no tagged entries
  119. $message = $DSP->qspan('alert', $LANG->line('no_entries'));
  120. }
  121. }
  122. // End synchronization routine
  123. // Start building the page
  124. $DSP->crumbline = TRUE;
  125. $DSP->title = $LANG->line('extension_settings');
  126. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  127. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=extensions_manager', $LANG->line('extensions_manager')));
  128. $DSP->crumb .= $DSP->crumb_item($this->name);
  129. $DSP->right_crumb($LANG->line('disable_extension'), BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=toggle_extension_confirm'.AMP.'which=disable'.AMP.'name='.$IN->GBL('name'));
  130. $DSP->body = '';
  131. if(isset($_GET['msg']) && $LANG->line($_GET['msg']))
  132. {
  133. $message = $DSP->qspan('success', $LANG->line($_GET['msg']));
  134. }
  135. // Do we have a message to show?
  136. if(isset($message))
  137. {
  138. $DSP->body .= $DSP->qdiv('box', $message);
  139. }
  140. $DSP->body .= $DSP->heading($this->name.NBS.$DSP->qspan('defaultLight', $this->version), 1);
  141. $DSP->body .= $DSP->form_open(
  142. array(
  143. 'action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=save_extension_settings',
  144. 'name' => 'tag_sync',
  145. 'id' => 'tag_sync'
  146. ),
  147. array('name' => get_class($this))
  148. );
  149. // Open the table
  150. $DSP->body .= $DSP->table('tableBorder', '0', '', '100%');
  151. $DSP->body .= $DSP->tr();
  152. $DSP->body .= $DSP->td('tableHeading');
  153. $DSP->body .= ucfirst($PREFS->ini('weblog_nomenclature'));
  154. $DSP->body .= $DSP->td_c();
  155. $DSP->body .= $DSP->td('tableHeading', '', 2);
  156. $DSP->body .= $LANG->line('tag_field');
  157. $DSP->body .= $DSP->td_c();
  158. $DSP->body .= $DSP->tr_c();
  159. // Display fair warning
  160. $DSP->body .= $DSP->tr();
  161. $DSP->body .= '<td class="box" style="border-width: 0 0 1px; margin: 0;" colspan="3">';
  162. $DSP->body .= $DSP->qspan('highlight bold', $LANG->line('important')).' ';
  163. $DSP->body .= $DSP->qspan('default', $LANG->line('warning'));
  164. $DSP->body .= $DSP->td_c();
  165. $DSP->body .= $DSP->tr_c();
  166. // Get a list of weblogs
  167. $query = $DB->query("SELECT blog_title, weblog_id FROM exp_weblogs WHERE site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' ORDER BY blog_title ASC");
  168. $i = 1;
  169. foreach($query->result as $row)
  170. {
  171. extract($row);
  172. $row_class = ($i % 2) ? 'tableCellTwo' : 'tableCellOne';
  173. // Get a list of text fields for this weblog
  174. $sql = "SELECT f.field_id, f.field_label FROM exp_weblogs as w, exp_weblog_fields as f
  175. WHERE w.field_group = f.group_id
  176. AND w.weblog_id = $weblog_id
  177. AND f.field_type IN ('text', 'textarea')
  178. ORDER BY f.field_order ASC";
  179. $results = $DB->query($sql);
  180. // Create a settings row for the weblog
  181. $DSP->body .= $DSP->tr();
  182. $DSP->body .= $DSP->td($row_class, '45%');
  183. $DSP->body .= $DSP->qdiv('defaultBold', $blog_title);
  184. $DSP->body .= $DSP->td_c();
  185. $DSP->body .= $DSP->td($row_class);
  186. $DSP->body .= $DSP->input_select_header('weblog_id_'.$weblog_id, null, null, '200px');
  187. $DSP->body .= $DSP->input_select_option('', '--');
  188. foreach($results->result as $value)
  189. {
  190. extract($value);
  191. $DSP->body .= $DSP->input_select_option($field_id, $field_label, ( isset($current['weblog_id_'.$weblog_id]) && $current['weblog_id_'.$weblog_id] == $field_id ) ? 1 : '');
  192. }
  193. $DSP->body .= $DSP->input_select_footer();
  194. $DSP->body .= $DSP->td_c();
  195. $DSP->body .= $DSP->td($row_class.' defaultBold');
  196. // Should we display the sync link?
  197. if( isset($current['weblog_id_'.$weblog_id]) && !empty($current['weblog_id_'.$weblog_id]) )
  198. {
  199. $DSP->body .= $DSP->anchor(
  200. BASE.AMP.
  201. 'C=admin'.
  202. AMP.'M=utilities'.
  203. AMP.'P=extension_settings'.
  204. AMP.'name=tag_sync'.
  205. AMP.'sync_weblog='.$weblog_id,
  206. $LANG->line('sync_weblog').' '.$PREFS->core_ini['weblog_nomenclature']
  207. );
  208. }
  209. else
  210. {
  211. $DSP->body .= NBS;
  212. }
  213. $DSP->body .= $DSP->td_c();
  214. $DSP->body .= $DSP->tr_c();
  215. $i++;
  216. }
  217. // Wrap it up
  218. $DSP->body .= $DSP->table_c();
  219. $DSP->body .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit());
  220. $DSP->body .= $DSP->form_c();
  221. }
  222. function save_settings()
  223. {
  224. global $DB, $FNS;
  225. // Get the current settings, as we don't want to
  226. // overwrite other sites' settings
  227. $settings = $this->get_settings();
  228. unset($_POST['name']);
  229. // Add to the existing settings array
  230. foreach($_POST AS $weblog => $field)
  231. {
  232. $settings[$weblog] = round($field); // Insures that it is an integer
  233. }
  234. $data = array('settings' => addslashes(serialize($settings)));
  235. $update = $DB->update_string('exp_extensions', $data, "class = 'Tag_sync'");
  236. $DB->query($update);
  237. $FNS->redirect(BASE.AMP.'C=admin'.
  238. AMP.'M=utilities'.
  239. AMP.'P=extension_settings'.
  240. AMP.'name=tag_sync'.
  241. AMP.'msg=settings_saved');
  242. exit;
  243. }
  244. function get_settings()
  245. {
  246. global $DB, $REGX;
  247. $get_settings = $DB->query("SELECT settings FROM exp_extensions WHERE class = 'Tag_sync' LIMIT 1");
  248. if ($get_settings->num_rows > 0 && $get_settings->row['settings'] != '')
  249. {
  250. $settings = $REGX->array_stripslashes(unserialize($get_settings->row['settings']));
  251. }
  252. else
  253. {
  254. $settings = array();
  255. }
  256. return $settings;
  257. }
  258. function submit_new_entry_absolute_end($entry_id, $data)
  259. {
  260. global $DB;
  261. if($this->settings)
  262. {
  263. $get_weblog = $DB->query('SELECT weblog_id FROM exp_weblog_titles WHERE entry_id = '.$entry_id);
  264. if( isset($this->settings['weblog_id_'.$get_weblog->row['weblog_id']]) && !empty($this->settings['weblog_id_'.$get_weblog->row['weblog_id']]) )
  265. {
  266. $custom_field = $this->settings['weblog_id_'.$get_weblog->row['weblog_id']];
  267. $sql = "SELECT DISTINCT t.tag_name FROM exp_tag_entries AS e LEFT JOIN exp_tag_tags AS t ON e.tag_id = t.tag_id WHERE e.entry_id = ".$entry_id;
  268. $get_tags = $DB->query($sql);
  269. if($get_tags->num_rows > 0)
  270. {
  271. $tags = array();
  272. foreach($get_tags->result as $tag)
  273. {
  274. $tags[] = $tag['tag_name'];
  275. }
  276. // Update the field with our list of tags
  277. $sql = "UPDATE exp_weblog_data SET `field_id_".ceil($custom_field)."` = '".$DB->escape_str(implode(',', $tags))."' WHERE entry_id = $entry_id";
  278. }
  279. else
  280. {
  281. // We don't have any tags, or just removed them all, so zero out the field
  282. $sql = "UPDATE exp_weblog_data SET `field_id_".ceil($custom_field)."` = '' WHERE entry_id = $entry_id";
  283. }
  284. $DB->query($sql);
  285. }
  286. }
  287. }
  288. // --------------------------------
  289. // Activate Extension
  290. // --------------------------------
  291. function activate_extension()
  292. {
  293. global $DB;
  294. $hooks = array(
  295. 'submit_new_entry_absolute_end' => 'submit_new_entry_absolute_end',
  296. );
  297. foreach($hooks as $hook => $method)
  298. {
  299. $DB->query($DB->insert_string('exp_extensions',
  300. array(
  301. 'extension_id' => '',
  302. 'class' => 'Tag_sync',
  303. 'method' => $method,
  304. 'hook' => $hook,
  305. 'settings' => '',
  306. 'priority' => 10,
  307. 'version' => $this->version,
  308. 'enabled' => "y"
  309. )
  310. )
  311. );
  312. }
  313. }
  314. // END
  315. // --------------------------------
  316. // Update Extension
  317. // --------------------------------
  318. function update_extension($current='')
  319. {
  320. global $DB;
  321. if ($current == '' OR $current == $this->version)
  322. {
  323. return FALSE;
  324. }
  325. if($current < '1.0.5')
  326. {
  327. // Zero the settings, as the field_id is stored as an integer now
  328. $data = array('settings' => serialize(array()));
  329. $update = $DB->update_string('exp_extensions', $data, "class = 'Tag_sync'");
  330. $DB->query($update);
  331. }
  332. $DB->query("UPDATE exp_extensions
  333. SET version = '".$DB->escape_str($this->version)."'
  334. WHERE class = 'Tag_sync'");
  335. }
  336. // END
  337. // --------------------------------
  338. // Disable Extension
  339. // --------------------------------
  340. function disable_extension()
  341. {
  342. global $DB;
  343. $DB->query("DELETE FROM exp_extensions WHERE class = 'Tag_sync'");
  344. }
  345. // END
  346. }
  347. // END CLASS