| 3 |
/** |
/** |
| 4 |
* Syncronize form. Contains lists of updated, added, and deleted templates. |
* Syncronize form. Contains lists of updated, added, and deleted templates. |
| 5 |
* |
* |
| 6 |
|
* @return |
| 7 |
|
* The rendered HTML of the page. |
| 8 |
|
*/ |
| 9 |
|
function skeleton_sync_page() { |
| 10 |
|
drupal_add_js(drupal_get_path('module', 'skeleton') . '/skeleton-admin.js'); |
| 11 |
|
$output .= drupal_get_form('skeleton_sync_content_form'); |
| 12 |
|
$output .= drupal_get_form('skeleton_sync_add_template_form'); |
| 13 |
|
$output .= drupal_get_form('skeleton_sync_delete_template_form'); |
| 14 |
|
return $output; |
| 15 |
|
} |
| 16 |
|
|
| 17 |
|
/** |
| 18 |
|
* Syncronize content form. |
| 19 |
|
* |
| 20 |
* @param $form_state |
* @param $form_state |
| 21 |
* The state of the form. |
* The state of the form. |
| 22 |
* @return |
* @return |
| 23 |
* The form array. |
* The form array. |
| 24 |
*/ |
*/ |
| 25 |
function skeleton_sync_form($form_state) { |
function skeleton_sync_content_form($form_state) { |
| 26 |
$form = array(); |
$form = array(); |
| 27 |
$form['help'] = array( |
$form['content'] = array( |
| 28 |
|
'#type' => 'fieldset', |
| 29 |
|
'#title' => t('Syncronize template content'), |
| 30 |
|
'#collapsible' => TRUE, |
| 31 |
|
); |
| 32 |
|
$form['content']['help'] = array( |
| 33 |
'#prefix' => '<p>', |
'#prefix' => '<p>', |
| 34 |
'#suffix' => '</p>', |
'#suffix' => '</p>', |
| 35 |
'#value' => t('Use this form to syncronize changed templates with pages which have all ready been created.'), |
'#value' => t('Use this form to syncronize changed templates with pages which have all ready been created.'), |
| 44 |
$updated[$node->nid] = t('<a href="@node-url">%title</a>, in the <a href="@book-url">%book-title</a> book, created from the <a href="@template-url">%template</a> template.', array('@node-url' => url('node/' . $node->nid), '%title' => $node->title, '@book-url' => url('node/' . $book->nid), '%book-title' => $book->title, '%template' => $eligble_node->template, '@template-url' => url('admin/content/skeleton/template/' . $eligble_node->template_id . '/view'))); |
$updated[$node->nid] = t('<a href="@node-url">%title</a>, in the <a href="@book-url">%book-title</a> book, created from the <a href="@template-url">%template</a> template.', array('@node-url' => url('node/' . $node->nid), '%title' => $node->title, '@book-url' => url('node/' . $book->nid), '%book-title' => $book->title, '%template' => $eligble_node->template, '@template-url' => url('admin/content/skeleton/template/' . $eligble_node->template_id . '/view'))); |
| 45 |
} |
} |
| 46 |
if (!empty($updated)) { |
if (!empty($updated)) { |
| 47 |
$form['nodes'] = array( |
$form['content']['#collapsed'] = FALSE; |
| 48 |
|
$form['content']['nodes'] = array( |
| 49 |
'#type' => 'checkboxes', |
'#type' => 'checkboxes', |
| 50 |
'#title' => t('Select the nodes you wish to update'), |
'#title' => t('Select the nodes you wish to update'), |
| 51 |
'#options' => $updated, |
'#options' => $updated, |
| 52 |
); |
); |
| 53 |
$form['submit'] = array( |
$form['content']['submit'] = array( |
| 54 |
'#type' => 'submit', |
'#type' => 'submit', |
| 55 |
'#value' => t('Synchronize'), |
'#value' => t('Synchronize'), |
| 56 |
); |
); |
| 57 |
} |
} |
| 58 |
else { |
else { |
| 59 |
$form['no_nodes'] = array( |
$form['content']['#collapsed'] = TRUE; |
| 60 |
|
$form['content']['no_nodes'] = array( |
| 61 |
'#prefix' => '<p>', |
'#prefix' => '<p>', |
| 62 |
'#suffix' => '</p>', |
'#suffix' => '</p>', |
| 63 |
'#value' => t('There are no nodes eligible for synchronizing.') |
'#value' => t('There are no nodes eligible for content synchronizing.') |
| 64 |
); |
); |
| 65 |
} |
} |
|
|
|
|
// TODO: Show a seperate list for new templates added to a skeleton. |
|
|
|
|
|
// TODO: Show a seperate list for templates removed from a skeleton. |
|
|
|
|
| 66 |
return $form; |
return $form; |
| 67 |
} |
} |
| 68 |
|
|
| 69 |
/** |
/** |
| 70 |
* Submit handler for the syncronize form. |
* Submit handler for the syncronize content form. |
| 71 |
* |
* |
| 72 |
* @param $form |
* @param $form |
| 73 |
* The form being submitted. |
* The form being submitted. |
| 75 |
* @param $form_state |
* @param $form_state |
| 76 |
* The state of the form. |
* The state of the form. |
| 77 |
*/ |
*/ |
| 78 |
function skeleton_sync_form_submit($form, $form_state) { |
function skeleton_sync_content_form_submit($form, $form_state) { |
| 79 |
$batch = array( |
$batch = array( |
| 80 |
'title' => t('Updating content'), |
'title' => t('Updating content'), |
| 81 |
'init_message' => t('Content updating is starting.'), |
'init_message' => t('Content updating is starting.'), |
| 90 |
} |
} |
| 91 |
|
|
| 92 |
/** |
/** |
| 93 |
|
* Form for pushing out new templates to existing skeletons. |
| 94 |
|
*/ |
| 95 |
|
function skeleton_sync_add_template_form($form_state) { |
| 96 |
|
$form = array(); |
| 97 |
|
$form['templates'] = array( |
| 98 |
|
'#type' => 'fieldset', |
| 99 |
|
'#title' => t('Syncronize templates'), |
| 100 |
|
'#collapsible' => TRUE, |
| 101 |
|
); |
| 102 |
|
// Find all copies of instantiated skeletons which do not contain a template |
| 103 |
|
// now associated with the same skeleton. |
| 104 |
|
$skeleton_result = db_query("SELECT DISTINCT skeleton_id FROM {skeleton_template_node}"); |
| 105 |
|
while ($skeleton_id = db_result($skeleton_result)) { |
| 106 |
|
$templates = array(); |
| 107 |
|
$updated = array(); |
| 108 |
|
$skeleton = skeleton_load($skeleton_id); |
| 109 |
|
$form['templates']['skeletons'] = array( |
| 110 |
|
'#tree' => TRUE, |
| 111 |
|
); |
| 112 |
|
$form['templates']['skeletons'][$skeleton_id] = array(); |
| 113 |
|
$template_result = db_query("SELECT DISTINCT template_id FROM {skeleton_template_node} WHERE skeleton_id = %d", $skeleton_id); |
| 114 |
|
while ($template_id = db_result($template_result)) { |
| 115 |
|
$templates[] = $template_id; |
| 116 |
|
} |
| 117 |
|
$updated_result = db_query("SELECT template_id FROM {skeleton_data} WHERE skeleton_id = %d AND template_id NOT IN (" . implode(',', $templates) . ")", $skeleton_id); |
| 118 |
|
while ($updated_id = db_result($updated_result)) { |
| 119 |
|
$template = skeleton_template_load($updated_id); |
| 120 |
|
$updated[$updated_id] = l($template->template, 'admin/content/skeleton/template/' . $template->template_id . '/view'); |
| 121 |
|
} |
| 122 |
|
if (!empty($updated)) { |
| 123 |
|
$form['templates']['skeletons'][$skeleton_id] = array( |
| 124 |
|
'#type' => 'checkboxes', |
| 125 |
|
'#title' => t('Create new pages from new templates assigned to <a href="@skeleton-url">%skeleton</a>', array('@skeleton-url' => url('admin/content/skeleton/skeleton/' . $skeleton->skeleton_id . '/edit'), '%skeleton' => $skeleton->skeleton)), |
| 126 |
|
'#options' => $updated, |
| 127 |
|
); |
| 128 |
|
$form['templates']['submit'] = array( |
| 129 |
|
'#type' => 'submit', |
| 130 |
|
'#value' => t('Syncronize'), |
| 131 |
|
); |
| 132 |
|
} |
| 133 |
|
else { |
| 134 |
|
$form['templates']['#collapsed'] = TRUE; |
| 135 |
|
$form['templates']['no_templates'] = array( |
| 136 |
|
'#prefix' => '<p>', |
| 137 |
|
'#suffix' => '</p>', |
| 138 |
|
'#value' => t('There are no templates eligible for content synchronizing.') |
| 139 |
|
); |
| 140 |
|
} |
| 141 |
|
} |
| 142 |
|
return $form; |
| 143 |
|
} |
| 144 |
|
|
| 145 |
|
/** |
| 146 |
|
* Submit handler for pushing out new templates to existing books. |
| 147 |
|
*/ |
| 148 |
|
function skeleton_sync_add_template_form_submit($form, &$form_state) { |
| 149 |
|
module_load_include('inc', 'node', 'node.pages'); |
| 150 |
|
module_load_include('inc', 'skeleton', 'skeleton_token'); |
| 151 |
|
foreach($form_state['values']['skeletons'] as $skeleton_id => $templates) { |
| 152 |
|
$templates = array_filter($templates); |
| 153 |
|
foreach($templates as $template_id) { |
| 154 |
|
// Find the template parent of this template |
| 155 |
|
// $template = skeleton_template_load($template_id); |
| 156 |
|
// If the parent is 0, we place it under the top-most book node. |
| 157 |
|
// Otherwise, place it under the parent template in the book. |
| 158 |
|
$parent = db_result(db_query("SELECT parent FROM {skeleton_data} WHERE skeleton_id = %d AND template_id = %d", $skeleton_id, $template_id)); |
| 159 |
|
if ($parent == 0) { |
| 160 |
|
// TODO! |
| 161 |
|
} |
| 162 |
|
else { |
| 163 |
|
$parent_nids_result = db_query("SELECT nid, tokens FROM {skeleton_template_node} WHERE skeleton_id = %d AND template_id = %d", $skeleton_id, $parent); |
| 164 |
|
while($parent_info = db_fetch_object($parent_nids_result)) { |
| 165 |
|
$parent_info->tokens = unserialize($parent_info->tokens); |
| 166 |
|
$data = db_result(db_query("SELECT node_data FROM {skeleton_template} WHERE template_id = %d", $template_id)); |
| 167 |
|
$node = array(); |
| 168 |
|
$node['values'] = unserialize($data); |
| 169 |
|
$parent_node = node_load($parent_info->nid, NULL, TRUE); |
| 170 |
|
$node['values']['book'] = array(); |
| 171 |
|
$node['values']['book']['bid'] = $parent_node->book['bid']; |
| 172 |
|
$node['values']['book']['plid'] = $parent_node->book['mlid']; |
| 173 |
|
$node['values']['book']['options'] = array(); |
| 174 |
|
|
| 175 |
|
// Allow use of the [bookpathalias] token from pathauto. |
| 176 |
|
if (module_exists('pathauto')) { |
| 177 |
|
$node['values']['title'] = str_replace('[bookpathalias]', drupal_get_path_alias($parent_node->path), $node['values']['title']); |
| 178 |
|
$node['values']['body'] = str_replace('[bookpathalias]', drupal_get_path_alias($parent_node->path), $node['values']['body']); |
| 179 |
|
} |
| 180 |
|
|
| 181 |
|
// Replace custom tokens in the title and body fields. Replace skeleton |
| 182 |
|
// tokens first so they may be used as node tokens such as [title]. |
| 183 |
|
if (!empty($parent_info->tokens)) { |
| 184 |
|
$node['values']['title'] = token_replace($node['values']['title'], 'skeleton', $parent_info->tokens); |
| 185 |
|
$node['values']['body'] = token_replace($node['values']['body'], 'skeleton', $parent_info->tokens); |
| 186 |
|
} |
| 187 |
|
|
| 188 |
|
$node['values']['title'] = token_replace($node['values']['title'], 'node', (object)$node['values']); |
| 189 |
|
$node['values']['body'] = token_replace($node['values']['body'], 'node', (object)$node['values']); |
| 190 |
|
|
| 191 |
|
$node['values']['uid'] = $parent_node->uid; |
| 192 |
|
$node['values']['name'] = $parent_node->name; |
| 193 |
|
|
| 194 |
|
$node['values']['tokens'] = $parent_info->tokens; |
| 195 |
|
|
| 196 |
|
// We have to add the skeleton ID here as we can't save it with the |
| 197 |
|
// template as a template may have multiple skeletons. |
| 198 |
|
$node['values']['skeleton_id'] = $skeleton_id; |
| 199 |
|
|
| 200 |
|
$node['values']['op'] = t('Save'); |
| 201 |
|
drupal_execute($node['values']['type'] .'_node_form', $node, (object)$node['values']); |
| 202 |
|
// TODO: This will probably need to be removed if this call is integrated |
| 203 |
|
// into the book module. See http://drupal.org/node/364529 for details. |
| 204 |
|
menu_rebuild(); |
| 205 |
|
$form_state['nids'][] = $node['nid']; |
| 206 |
|
} |
| 207 |
|
} |
| 208 |
|
} |
| 209 |
|
} |
| 210 |
|
} |
| 211 |
|
|
| 212 |
|
/** |
| 213 |
|
* Form for deleting instantiated templates where the source template has been |
| 214 |
|
* deleted. |
| 215 |
|
*/ |
| 216 |
|
function skeleton_sync_delete_template_form($form_state) { |
| 217 |
|
$form = array(); |
| 218 |
|
$form['delete'] = array( |
| 219 |
|
'#type' => 'fieldset', |
| 220 |
|
'#title' => t('Delete instantiated template nodes'), |
| 221 |
|
'#collapsible' => TRUE, |
| 222 |
|
); |
| 223 |
|
$form['delete']['help'] = array( |
| 224 |
|
'#prefix' => '<p>', |
| 225 |
|
'#suffix' => '</p>', |
| 226 |
|
'#value' => t("Use this form to delete nodes where the associated template has also been deleted."), |
| 227 |
|
); |
| 228 |
|
$form['delete']['nodes'] = array( |
| 229 |
|
'#tree' => TRUE, |
| 230 |
|
); |
| 231 |
|
|
| 232 |
|
// Find all nodes where the template it was created from has been deleted. |
| 233 |
|
$result = db_query("SELECT nid from {skeleton_template_node} stn LEFT JOIN {skeleton_template} st ON stn.template_id = st.template_id WHERE st.template_id IS NULL"); |
| 234 |
|
$options = array(); |
| 235 |
|
while ($node = node_load(db_result($result))) { |
| 236 |
|
$book = node_load($node->book['bid']); |
| 237 |
|
$options[$node->nid] = t('<a href="@node-url">%title</a>, in the <a href="@book-url">%book-title</a> book.', array('@node-url' => url('node/' . $node->nid), '%title' => $node->title, '@book-url' => url('node/' . $book->nid), '%book-title' => $book->title)); |
| 238 |
|
} |
| 239 |
|
if (!empty($options)) { |
| 240 |
|
$form['delete']['nodes'] = array( |
| 241 |
|
'#type' => 'checkboxes', |
| 242 |
|
'#title' => t('Select the nodes you wish to delete'), |
| 243 |
|
'#options' => $options, |
| 244 |
|
); |
| 245 |
|
$form['delete']['submit'] = array( |
| 246 |
|
'#type' => 'submit', |
| 247 |
|
'#value' => t('Delete selected nodes'), |
| 248 |
|
); |
| 249 |
|
} |
| 250 |
|
else { |
| 251 |
|
$form['delete']['#collapsed'] = TRUE; |
| 252 |
|
$form['delete']['no_nodes'] = array( |
| 253 |
|
'#prefix' => '<p>', |
| 254 |
|
'#suffix' => '</p>', |
| 255 |
|
'#value' => t('There are no nodes with deleted templates.') |
| 256 |
|
); |
| 257 |
|
} |
| 258 |
|
return $form; |
| 259 |
|
} |
| 260 |
|
|
| 261 |
|
/** |
| 262 |
|
* Submit handler for deleting nodes where the associated template has also |
| 263 |
|
* been deleted. |
| 264 |
|
*/ |
| 265 |
|
function skeleton_sync_delete_template_form_submit($form, &$form_state) { |
| 266 |
|
$batch = array( |
| 267 |
|
'title' => t('Deleting content'), |
| 268 |
|
'init_message' => t('Content deletion is starting.'), |
| 269 |
|
'progress_message' => t('Processed @current out of @total.'), |
| 270 |
|
'error_message' => t('There was an error while updating content.'), |
| 271 |
|
'file' => drupal_get_path('module', 'skeleton'). '/skeleton_sync.inc', |
| 272 |
|
); |
| 273 |
|
foreach (array_filter($form_state['values']['nodes']) as $nid) { |
| 274 |
|
$batch['operations'][] = array('skeleton_sync_delete_node', array($nid)); |
| 275 |
|
} |
| 276 |
|
if (!empty($batch['operations'])) { |
| 277 |
|
batch_set($batch); |
| 278 |
|
} |
| 279 |
|
} |
| 280 |
|
|
| 281 |
|
/** |
| 282 |
* Update an instantiated node based on an updated template. |
* Update an instantiated node based on an updated template. |
| 283 |
* |
* |
| 284 |
* @param $nid |
* @param $nid |
| 320 |
db_query("UPDATE {skeleton_template_node} SET template_status = 'synced' WHERE nid = %d", $node->nid); |
db_query("UPDATE {skeleton_template_node} SET template_status = 'synced' WHERE nid = %d", $node->nid); |
| 321 |
$context['results'][] = t('Updated %title', array('%title' => $node->title)); |
$context['results'][] = t('Updated %title', array('%title' => $node->title)); |
| 322 |
} |
} |
| 323 |
|
|
| 324 |
|
/** |
| 325 |
|
* Delete an instantiated node. This is used to delete nodes where it's |
| 326 |
|
* template has also been deleted, but could also be used to delete any node. |
| 327 |
|
* |
| 328 |
|
* @param $nid |
| 329 |
|
* The node ID to delete. |
| 330 |
|
* |
| 331 |
|
* @param &$context |
| 332 |
|
* The current context of the batch operation. |
| 333 |
|
*/ |
| 334 |
|
function skeleton_sync_delete_node($nid, &$context) { |
| 335 |
|
$node = node_load($nid); |
| 336 |
|
node_delete($nid); |
| 337 |
|
$context['results'][] = t('Deleted %title', array('%title' => $node->title)); |
| 338 |
|
} |