Refactor currentPhase code to account for changes in the API (addition of "type"...
[project/lingotek.git] / lingotek.page.inc
1 <?php
2 /**
3 * @file
4 * Lingotek Tab for Nodes
5 */
6
7 /**
8 * Page callback for the Lingotek local task on node detail pages.
9 *
10 * Construct the table summarizing information a Product Manager would want
11 * to know about the progress of the translations.
12 *
13 * @return array
14 * A Drupal render array of the page contents.
15 */
16 function lingotek_pm($node) {
17 $output = array();
18
19 drupal_add_js(drupal_get_path('module', 'lingotek') . '/js/lingotek.pm.js');
20
21 if (class_exists('LingotekDocument')) {
22 $checkbox = '<input type="checkbox" onchange="lingotek.pm.toggle_checkboxes(this);" />';
23 $headers = array(
24 $checkbox,
25 t('Target Language'),
26 t('Document Progress'),
27 t('Phase'),
28 t('Phase Progress'),
29 t('Phase Complete'),
30 );
31
32 $document = LingotekDocument::load(lingotek_lingonode($node->nid, 'document_id_' . $node->language));
33
34 $progress = lingotek_get_document_targets($document->document_id, TRUE);
35
36 $rows = array();
37 foreach ($progress as $language => $target) {
38 $current_phase = $document->currentPhase($target->id);
39 $phase_complete = ($current_phase->isMarkedComplete) ? TRUE : FALSE;
40 $phase_complete_percent = $current_phase->percentComplete;
41 if (empty($phase_complete_percent)) {
42 $phase_complete_percent = 0;
43 }
44 $row = array(
45 '<input type="checkbox" tag="lingotek_pm_row" language="' . $language . '" />',
46 lingotek_language_native($language) . ' (' . lingotek_language_name($language) . ')',
47 $target->percentComplete . '%',
48 lingotek_get_workbench_url($node, $language, TRUE),
49 $phase_complete_percent . '%',
50 ($phase_complete) ? '<img src="' . url(drupal_get_path('module', 'lingotek') . '/images/ico_tick_17x.png') . '" />' : '',
51 );
52 lingotek_trace("lingotek_pm table row", array('language' => $language));
53 $rows[] = $row;
54 }
55 $table = theme('table', array('header' => $headers, 'rows' => $rows));
56
57 $actions = '<input type="button" id="lingotek-update-button" value="' . t('Update') . '"/>';
58
59 $vars = '<input type="hidden" id="lingotek_nid" value="' . $node->nid . '" />';
60
61 $token_element = array(
62 '#type' => 'hidden',
63 '#attributes' => array('id' => 'submit-token'),
64 '#value' => drupal_get_token(),
65 );
66 $vars .= drupal_render($token_element);
67
68 $pull_translations = array();
69
70 $pull_translations['fieldset'] = array(
71 '#type' => 'fieldset',
72 '#title' => t('Pull translations from Lingotek'),
73 '#description' => t('Pull the latest translations from Lingotek in the selected languages.'),
74 '#collapsible' => TRUE,
75 '#collapsed' => FALSE,
76 );
77
78 $pull_translations['fieldset']['contents'] = array(
79 '#markup' => $table . $actions . $vars,
80 );
81
82 if (lingotek_supported_type($node->type) && lingotek_supported_language($node->language)) {
83 $output['content_push'] = array(
84 '#markup' => (lingotek_lingonode($node->nid, 'create_lingotek_document')) ? '' : drupal_render(drupal_get_form('lingotek_content_push_form', $node)),
85 );
86
87 if (!empty($rows)) {
88 $output['content_pull'] = array(
89 '#markup' => drupal_render($pull_translations),
90 );
91 }
92 }
93 else {
94 $output['content_pull'] = array(
95 '#markup' => '<p class="help">' . t('This node is not compatible with Lingotek translation. Either it is not a Lingotek tranlsation-enabled content type. Or the node does not have a defined language.') . '</p>'
96 );
97 }
98
99 // Add the mark as complete table if there are complete-eligible phrases.
100 if ($document->hasPhasesToComplete()) {
101 $output['mark_complete'] = array(
102 '#markup' => drupal_render(drupal_get_form('lingotek_mark_phases_complete', $node)),
103 );
104 }
105
106 $output['upgrade_form'] = array(
107 '#markup' => drupal_render(drupal_get_form('lingotek_advanced_parsing_upgrade_form')),
108 );
109 }
110
111 return $output;
112 }
113
114 /*
115 * Synchonize translations with what is available on the Lingotek platform (current translations)
116 */
117 function lingotek_update($nid) {
118 $node = node_load($nid);
119 foreach ($_POST['targets'] as $target) {
120 lingotek_download_document($node, check_plain($target));
121 }
122 drupal_set_message(t('Updated local translations for the selected languages.'));
123 drupal_json_output(array('status' => 0, 'updated' => $_POST['targets'], 'nid' => $nid));
124 }
125
126 /**
127 * Form constructor for parsing upgrade of a node.
128 *
129 * @return array
130 * A FAPI form array.
131 */
132 function lingotek_advanced_parsing_upgrade_form($form_state) {
133 $form = array();
134
135 if (!variable_get('lingotek_advanced_parsing', FALSE)) {
136 $router_item = menu_get_item();
137 if (!empty($router_item['page_arguments'][0]->nid)) {
138 $node_id = $router_item['page_arguments'][0]->nid;
139
140 $form['node_id'] = array(
141 '#type' => 'hidden',
142 '#value' => $node_id,
143 );
144
145 $form['advanced_parsing_upgrade'] = array(
146 '#type' => 'fieldset',
147 '#title' => t('Advanced Content Parsing'),
148 '#description' => t('Your site is currently set to use legacy ("simple") content parsing. Use the button below to upgrade this node to advanced content parsing.'),
149 '#collapsible' => TRUE,
150 '#collapsed' => TRUE,
151 );
152
153 $advanced_parsing = lingotek_lingonode($node_id, 'use_advanced_parsing');
154 if (empty($advanced_parsing)) {
155 $form['advanced_parsing_upgrade']['submit'] = array(
156 '#type' => 'submit',
157 '#value' => t('Upgrade node'),
158 );
159 }
160 else {
161 $form['advanced_parsing_upgrade']['already_upgraded'] = array(
162 '#markup' => t('This node has already been upgraded to use advanced parsing.')
163 );
164 }
165 }
166 else {
167 watchdog('lingotek', 'Unable to locate node ID for advanced parsing upgrade form: @path', array('@path' => $_GET['q']), WATCHDOG_ERROR);
168 }
169 }
170
171 return $form;
172 }
173
174
175 /**
176 * Submit handler for the lingotek_advanced_parsing_upgrade_form form.
177 *
178 * @param array $form
179 * A FAPI form array.
180 * @param array $form_state
181 * A FAPI form state array.
182 */
183 function lingotek_advanced_parsing_upgrade_form_submit($form, $form_state) {
184 $error = FALSE;
185
186 if (!empty($form_state['values']['node_id'])) {
187 lingotek_lingonode($form_state['values']['node_id'], 'use_advanced_parsing', 1);
188 $target_node = node_load($form_state['values']['node_id']);
189 if ($target_node->nid) {
190 if (LingotekApi::instance()->updateContentDocument($target_node)) {
191 drupal_set_message(t('This node has been upgraded to use advanced content parsing.'));
192 }
193 else {
194 $error = TRUE;
195 watchdog('lingotek', 'Error updating node for advanced content parsing. Lingotek updateContentDocument call failed.', NULL, WATCHDOG_ERROR);
196 }
197 }
198 else {
199 $error = TRUE;
200 watchdog('lingotek', 'Unable to load target node for content parsing upgrade: @node_id',
201 array('@node_id' => $form_state['values']['node_id']), WATCHDOG_ERROR);
202 }
203 }
204 else {
205 $error = TRUE;
206 watchdog('lingotek', 'No target node ID in parsing upgrade form data.', NULL, WATCHDOG_ERROR);
207 }
208
209 if ($error) {
210 drupal_set_message(t('There was an error upgrading this node. It has <strong>not</strong> been updated to use advanced parsing.'), 'error');
211 }
212 }
213
214 /**
215 * Form constructor for the lingotek_mark_phases_complete form.
216 *
217 * @param array $form
218 * A FAPI form array.
219 * @param array $form_state
220 * A FAPI form state array.
221 * @param object $node
222 * The Drupal node whose complete-eligible phases should be displayed.
223 *
224 * @return array
225 * A FAPI form data array.
226 */
227 function lingotek_mark_phases_complete($form, $form_state, $node) {
228 $form = array();
229
230 $document_id = lingotek_lingonode($node->nid, 'document_id_' . $node->language);
231 if (class_exists('LingotekDocument') && class_exists('LingotekPhase') && $document_id) {
232 $api = LingotekApi::instance();
233
234 $document = LingotekDocument::load($document_id);
235 if ($progress = $document->translationProgress()) {
236 $targets = $progress->translationTargets;
237
238 foreach ($targets as $target) {
239 $language = lingotek_drupal_language($target->language);
240 $current_phase = $document->currentPhase($target->id);
241
242 $phase_complete_percent = $current_phase->percentComplete;
243 if (empty($phase_complete_percent)) {
244 $phase_complete_percent = 0;
245 }
246
247 if ($current_phase && $current_phase->canBeMarkedComplete()) {
248 $phase_link = l($current_phase->name, '#', array('attributes' => array(
249 'onclick' => 'window.open(\'' . $api->getWorkbenchLink($document_id, $current_phase->id) . '\'); return false;')));
250
251 $row = array(
252 lingotek_language_native($language) . ' (' . lingotek_language_name($language) . ')',
253 $phase_link,
254 $phase_complete_percent . '%',
255 );
256
257 $options[$current_phase->id] = $row;
258 }
259 }
260
261 $form['mark_complete'] = array(
262 '#type' => 'fieldset',
263 '#title' => t('Mark Workflow Phases complete'),
264 '#description' => t('The following Translation Targets have Phases that can be marked as complete.'),
265 );
266
267 $form['mark_complete']['phases'] = array(
268 '#type' => 'tableselect',
269 '#header' => array(
270 t('Target Language'),
271 t('Phase'),
272 t('Phase Progress'),
273 ),
274 '#options' => $options,
275 );
276
277 $form['mark_complete']['submit'] = array(
278 '#type' => 'submit',
279 '#value' => t('Mark Selected Phases as Complete'),
280 );
281 }
282 else {
283 watchdog('lingotek', 'Unable to build mark as complete form: could not get progress data from API.',
284 NULL, WATCHDOG_ERROR);
285 }
286 }
287
288 return $form;
289 }
290
291 /**
292 * Submit handler for the lingotek_mark_phases_complete form.
293 */
294 function lingotek_mark_phases_complete_submit($form, $form_state) {
295 if (!empty($form_state['values']['phases'])) {
296 $api = LingotekApi::instance();
297 $errors = FALSE;
298 foreach ($form_state['values']['phases'] as $phase_id) {
299 if ($phase_id) {
300 if (!$api->markPhaseComplete($phase_id)) {
301 $errors = TRUE;
302 }
303 }
304 }
305
306 if (!$errors) {
307 drupal_set_message(t('All selected phases were marked as complete.'));
308 }
309 else {
310 drupal_set_message(t('There were errors marking one or more phases as complete.'), 'error');
311 }
312 }
313 else {
314 drupal_set_message(t('No phases were selected.'), 'error');
315 }
316 }