Projet

Général

Profil

Paste
Télécharger (14,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / sweaver / drush / sweaver.drush.inc @ 76df55b7

1
<?php
2

    
3
/**
4
 * @file
5
 * Sweaver Drush functions.
6
 *
7
 * While this is crazy and probably not something that will be
8
 * used a lot, it's jolly good fun to program this :).
9
 */
10

    
11
/**
12
 * Implementation of hook_drush_help().
13
 */
14
function sweaver_drush_help($section) {
15
  switch ($section) {
16
    case 'drush:sweaver-edit':
17
      return dt('Edit a style known by Sweaver. With no arguments, the command will list all available styles, after that just add the id as an argument.');
18
    case 'drush:sweaver-variables':
19
      return dt('Set some variables for Sweaver. With no arguments, the command will list the default values. Supply "type" and "value" as arguments. You can currently set the editor and the warning message to your likings (defaults to vi and true).');
20
  }
21
}
22

    
23

    
24
/**
25
 * Implementation of hook_drush_command().
26
 */
27
function sweaver_drush_command() {
28
  $items = array();
29

    
30
  $items['sweaver-edit'] = array(
31
    'callback' => 'sweaver_drush_style',
32
    'description' => dt('Edit the style with your favorite Editor.'),
33
    'arguments' => array(
34
      'style_id' => dt('A style ID'),
35
    ),
36
    'aliases' => array('swe'),
37
  );
38

    
39
  $items['sweaver-variables'] = array(
40
    'callback' => 'sweaver_drush_variables',
41
    'description' => dt('Set variables for running Sweaver with drush.'),
42
    'arguments' => array(
43
      'type' => dt('The type of variable to store. Currenlty only "editor" or "warning".'),
44
      'value' => dt('The value of the variable. Currently your favorite editor command (+ any arguments if needed) or "true" or "false" for the warning message.'),
45
    ),
46
    'aliases' => array('swv'),
47
  );
48

    
49
  return $items;
50
}
51

    
52
/**
53
 * Edit a style via drush.
54
 *
55
 * @param $args
56
 *   Arguments passed by the CLI.
57
 *
58
 * @return $mixed
59
 *   Either a list of styles or start up the editor functionality.
60
 */
61
function sweaver_drush_style() {
62
  $args = func_get_args();
63
  $styles = sweaver_drush_list_styles();
64
  $action = sweaver_drush_verify($args);
65

    
66
  switch ($action) {
67
    case 'list':
68
      return sweaver_drush_print_styles($styles);
69
      break;
70
    case 'edit':
71
      if (isset($styles[$args[0]])) {
72
        sweaver_drush_verify_edit($styles[$args[0]]);
73
        return sweaver_drush_edit_style($styles[$args[0]]);
74
      }
75
      drush_print(dt('Style id does not exists.'));
76
  }
77
}
78

    
79
/**
80
 * Edit a style.
81
 *
82
 * @param $style
83
 *   A style object from the Database.
84
 */
85
function sweaver_drush_edit_style($style) {
86

    
87
  $warning = variable_get('sweaver_drush_warning_edit', 'true');
88
  $editor = variable_get('sweaver_drush_editor', 'vi');
89

    
90
  // Display the warning text if needed.
91
  if ($warning == 'true') {
92
    $return = drush_confirm(sweaver_drush_warning_text());
93
    if (!$return) {
94
      // Bail out.
95
      drush_set_context("DRUSH_EXECUTION_COMPLETED", TRUE);
96
      drush_print(dt('Editing of style aborted.'));
97
      exit();
98
    }
99
  }
100

    
101
  // Prepare the css variable from the editor.
102
  $css = json_decode($style->css);
103
  $css = (!empty($css)) ? sweaver_drush_json_to_css($css) : '';
104

    
105
  // Create a static $data variable with CTools.
106
  $data = &drupal_static('sweaver_drush_style_data' , array());
107
  $data = array(
108
    'style' => $style,
109
    'editor' => $editor,
110
    'ts_enabled' => FALSE,
111
  );
112

    
113
  // Get some plugins.
114
  $sweaver = Sweaver::get_instance();
115
  $sweaver_cs = $sweaver->get_plugin('sweaver_plugin_customcss');
116
  $sweaver_ts = $sweaver->get_plugin('sweaver_plugin_themesettings');
117

    
118
  // Create steps array.
119
  $steps = array(
120
    'css' => $css
121
  );
122
  // Add custom css if enabled.
123
  if ($sweaver_cs) {
124
    $steps['customcss'] = $style->customcss;
125
  }
126
  // Add themesettings if enabled.
127
  if ($sweaver_ts) {
128
    $data['ts_enabled'] = TRUE;
129
    $steps['themesettings'] = sweaver_drush_array_to_string($style->themesettings);
130
  }
131
  $data['steps'] = $steps;
132

    
133
  // Step through.
134
  foreach ($steps as $step => $step_value) {
135

    
136
    // Ask confirmation first.
137
    $edit = drush_confirm(dt('Do you want to edit the @step ?', array('@step' => $step)));
138

    
139
    if ($edit) {
140
      $temp_file = drush_save_data_to_temp_file($step_value);
141
      $data['tempfiles'][$step] = $temp_file;
142
      $data['current_step'] = $step;
143
      $edit_command = $editor .' '. $temp_file;
144
      $pipes = array();
145

    
146
      // Opend the editor.
147
      proc_close(proc_open($edit_command, array(0 => STDIN, 1 => STDOUT, 2 => STDERR), $pipes));
148

    
149
      // We need to save the new content already here, because we lose the temporary data file.
150
      $step = $data['current_step'];
151
      $temp_file = $data['tempfiles'][$step];
152
      if ($content = file_exists($temp_file)) {
153
        switch ($step) {
154
          case 'css':
155
            $css = file_get_contents($temp_file);
156
            $style->write_css = $css;
157
            $style->css = sweaver_drush_css_to_json($css);
158
            break;
159
          case 'customcss':
160
            $data['style']->customcss = file_get_contents($temp_file);
161
            break;
162
          case 'themesettings':
163
            $data['style']->themesettings = serialize(sweaver_drush_array_lines_to_array_key_values(file($temp_file)));
164
            break;
165
        }
166
      }
167
    }
168
  }
169

    
170
  // Get the variables again.
171
  $style = $data['style'];
172
  $steps = $data['steps'];
173

    
174
  // Do we want to save ?
175
  $message = 'Do you want to save all changes ?';
176
  if (isset($style->active) && $style->active) {
177
    $message = 'Do you want to save all changes ? All changes will be visible for your visitors.';
178
  }
179
  $save = drush_confirm(dt($message));
180

    
181
  // No save.
182
  if (!$save) {
183
    drush_print(dt('Saving aborted, but was\'t this jolly good fun ? :)'));
184
  }
185

    
186
  // Let's save!
187
  else {
188
    // Get sweaver plugin styles.
189
    $sweaver_styles = $sweaver->get_plugin('sweaver_plugin_styles');
190

    
191
    // Save into database.
192
    $update = array('style_id');
193

    
194
    // Create stylesheet.
195
    $stylesheet = $style->write_css;
196
    $stylesheet .= "\n". $style->customcss;
197

    
198
    // Save draft version.
199
    if (!isset($style->active)) {
200
      drupal_write_record('sweaver_style_draft', $style, $update);
201
      $sweaver_styles->sweaver_export_file($stylesheet, $style);
202
      drush_print(dt('Draft version has been saved.'));
203
    }
204

    
205
    // Save live version.
206
    if (isset($style->active)) {
207
      drupal_write_record('sweaver_style', $style, $update);
208
      drush_print(dt('Live version has been saved.'));
209
    }
210

    
211
    // Export css files and set themesettings.
212
    if (isset($style->active)) {
213
      $sweaver_styles->sweaver_export_file($stylesheet, $style, 'live');
214
      if ($data['ts_enabled']) {
215
        $theme_settings_var = str_replace('/', '_', 'theme_'. $style->theme .'_settings');
216
        variable_set($theme_settings_var, unserialize($style->themesettings));
217
      }
218
    }
219

    
220
    // Flush cache.
221
    sweaver_clear_cache();
222
  }
223
}
224

    
225
/**
226
 * Print a list of styles.
227
 *
228
 * @param $styles
229
 *   A collection of draft styles.
230
 */
231
function sweaver_drush_print_styles($styles) {
232
  if (empty($styles)) {
233
    drush_print('No styles found in the system');
234
  }
235
  else {
236
    foreach ($styles as $key => $style) {
237
      unset($styles[$key]->css);
238
      unset($styles[$key]->customcss);
239
      unset($styles[$key]->themesettings);
240
      $style->style_id = $key;
241
      if (isset($style->active)) {
242
        $style->style = $style->style .' '. dt('(live)');
243
        unset($style->active);
244
      }
245
    }
246
    $rows = array(0 => array(dt('ID'), dt('Theme'), dt('Name')));
247
    $rows += $styles;
248
    drush_print_table($rows, TRUE);
249
  }
250
}
251

    
252
/**
253
 * Get the styles available in the system.
254
 */
255
function sweaver_drush_list_styles() {
256
  $styles = array();
257

    
258
  if (module_exists('sweaver')) {
259

    
260
    $i = 1;
261

    
262
    // Draft versions.
263
    $results = db_query("SELECT * FROM {sweaver_style_draft}")->fetchAll();
264
    foreach ($results as $row) {
265
      $styles[$i] = $row;
266
      $i++;
267
    }
268

    
269
    // Live versions.
270
    $results = db_query("SELECT * FROM {sweaver_style} where active = 1")->fetchAll();
271
    foreach ($results as $row) {
272
      $styles[$i] = $row;
273
      $i++;
274
    }
275
  }
276
  else {
277
    drush_set_context("DRUSH_EXECUTION_COMPLETED", TRUE);
278
    drush_print('Sweaver is not installed.');
279
    exit();
280
  }
281

    
282
  return $styles;
283
}
284

    
285
/**
286
 * Set Sweaver variables via Drush.
287
 *
288
 * @param $args
289
 *   Arguments passed by the CLI.
290
 *
291
 * @return $mixed
292
 *   Either a list of styles or start up the editor functionality.
293
 */
294
function sweaver_drush_variables() {
295
  $args = func_get_args();
296
  $action = sweaver_drush_verify($args, 'variables');
297

    
298
  switch ($action) {
299
    case 'list':
300
      drush_print(dt('Your favorite editor is currently @editor.', array('@editor' => variable_get('sweaver_drush_editor', 'vi'))));
301
      drush_print(dt('Warning message currently set to @warning.', array('@warning' => variable_get('sweaver_drush_warning_edit', 'true'))));
302
      break;
303

    
304
    case 'save':
305
      if ($args[0] == 'tmp') {
306
        variable_set('sweaver_drush_editor', $args[1]);
307
        drush_print(dt('Temporary directory set to @tmp.', array('@tmp' => $args[1])));
308
      }
309
      elseif ($args[0] == 'warning') {
310
        variable_set('sweaver_drush_warning_edit', $args[1]);
311
        drush_print(dt('Style warning set to @warning.', array('@warning' => $args[1])));
312
      }
313
      else {
314
        drush_print(dt('The first argument can only be "editor" or "warning"'));
315
      }
316
      break;
317
  }
318
}
319

    
320
/**
321
 * Verify arguments.
322
 *
323
 * @param $args
324
 *   A collection of arguments passed by cli.
325
 * @param $type
326
 *   Whether we need to verify styles or variables.
327
 * @return $string
328
 *   Which action to undertake.
329
 */
330
function sweaver_drush_verify($args, $type = 'styles') {
331
  if (empty($args)) {
332
    return 'list';
333
  }
334

    
335
  if ($type == 'styles' && isset($args[0]) && is_numeric($args[0])) {
336
    return 'edit';
337
  }
338

    
339
  if ($type == 'variables' && isset($args[0]) && is_string($args[0]) && isset($args[1]) && is_string($args[1])) {
340
    return 'save';
341
  }
342
  else {
343
    drush_print(dt('Wrong variables supplied.'));
344
  }
345
}
346

    
347
/**
348
 * Verify if drush can write into the sweaver files directory.
349
 */
350
function sweaver_drush_verify_edit($style) {
351
  $write = TRUE;
352
  $public_path = variable_get('file_public_path', conf_path() . '/files');
353
  $draft_file = $public_path . '/sweaver/sweaver_' . $style->theme .'_' . $style->style_id . '_draft.css';
354
  $live_file = $public_path . '/sweaver/sweaver_' . $style->theme .'_' . $style->style_id . '_live.css';
355
  $touch_file = (isset($style->active)) ? $live_file : $draft_file;
356
  $write = @touch($touch_file);
357

    
358
  if (!$write) {
359
    drush_set_context("DRUSH_EXECUTION_COMPLETED", TRUE);
360
    drush_print(dt('The drush user is not able to overwrite the files in the sweaver directory. Either change the permissions (best option) of those files or run Drush with sudo permissions (might conflict later on when editing the style again from the interface.)'));
361
    exit();
362
  }
363
}
364

    
365
/**
366
 * Convert the properties which are collected by the editor.
367
 * They are saved in the database as a JSON object but all
368
 * properties do not have their pre- and/or suffix on them.
369
 *
370
 * @param $css
371
 *   A collection of properties and values configured by the editor.
372
 * $return $new_css
373
 */
374
function sweaver_drush_json_to_css($css) {
375
  ctools_include('css');
376

    
377
  $new_css = clone($css);
378
  $sweaver_properties = sweaver_object_load(NULL, 'property');
379

    
380
  foreach ($css as $selector => $properties) {
381
    foreach ($properties as $property => $value) {
382
      if (isset($sweaver_properties[$property])) {
383

    
384
        // Get the property.
385
        $sp = $sweaver_properties[$property];
386

    
387
        // Add prefixes and suffixes, but skip special cases.
388
        if (($property == 'background-color' && $value == 'transparent') || ($property == 'background-image' && $value == 'none')) {
389
          continue;
390
        }
391
        $new_value = $sp->property_prefix . $value . $sp->property_suffix;
392
        $new_css->$selector->$property = $new_value;
393
      }
394
    }
395
  }
396

    
397
  return ctools_css_assemble($new_css);
398
}
399

    
400
/**
401
 * Convert the stylesheet back to JSON format.
402
 *
403
 * @param $css
404
 *   A stylesheet.
405
 * $return $json_css
406
 */
407
function sweaver_drush_css_to_json($css) {
408
  ctools_include('css');
409

    
410
  $json_css = new stdClass;
411
  $ctools_css = ctools_css_disassemble($css);
412
  $sweaver_properties = sweaver_object_load(NULL, 'property');
413

    
414
  foreach ($ctools_css as $selector => $properties) {
415
    foreach ($properties as $property => $value) {
416
      if (isset($sweaver_properties[$property])) {
417

    
418
        // Get the property.
419
        $sp = $sweaver_properties[$property];
420
        // Use str replaces to remove prefixes, suffixes and ;
421
        $new_value = str_replace(array($sp->property_prefix, $sp->property_suffix, ';'), '', $value);
422
        $json_css->$selector->$property = $new_value;
423
      }
424
    }
425
  }
426

    
427
  return json_encode($json_css);
428
}
429

    
430
/**
431
 * Convert an array to string.
432
 *
433
 * @param $array
434
 *   A collection of key value pairs.
435
 * @return $string
436
 */
437
function sweaver_drush_array_to_string($array) {
438
  $string = '';
439

    
440
  if (is_string($array)) {
441
    $array = unserialize($array);
442
  }
443

    
444
  if (is_array($array) && !empty($array)) {
445
    foreach ($array as $key => $value) {
446
      $string .= "$key : $value\n";
447
    }
448
  }
449

    
450
  return $string;
451
}
452

    
453
/**
454
 * Convert a string to array.
455
 *
456
 * @param $array
457
 *   A collection of key value pairs where the value should be exploded.
458
 * @return $array
459
 */
460
function sweaver_drush_array_lines_to_array_key_values($array) {
461
  $new_array = array();
462

    
463
  foreach ($array as $key => $line) {
464
    $key_value = explode(":", $line);
465
    $new_array_key = trim(array_shift($key_value));
466
    $new_array_value = trim(implode('', $key_value));
467
    $new_array[$new_array_key] = $new_array_value;
468
  }
469

    
470
  return $new_array;
471
}
472

    
473
/**
474
 * Warning text.
475
 *
476
 * @return $warning
477
 *   The warning text before editing a style.
478
 */
479
function sweaver_drush_warning_text() {
480
  $warning = '
481
/////////////////////////////
482
/// IMPORTANT, PLEASE READ //
483
/////////////////////////////
484

    
485
You are about to edit a style. This happens in a few steps. You
486
will get a confirmation question for each step available.
487
You can remove this warning by typing "drush swv warning false".
488

    
489
Step 1
490
------
491
Edit the general css which has been created by the style editor.
492
Due to the nature that the editor works, not all css properties are
493
valid, most regareding properties which can take multiple arguments like
494
margin, padding and border. For instance o do not use padding: 0 3 4 1, but
495
padding-x: 0; instead. You can always use the custom css of course where
496
you are free to enter what you like.
497

    
498
Step 2
499
------
500
Edit the custom css. You can edit this like a normal stylesheet.
501

    
502
Step 3
503
------
504
Edit the themesettings when the themesettings plugin is enabled.
505
Some values are booleans in the database. So: 0 = false, set to 1 to become true.
506
It will be presented like this. Do not remove the colons.
507
$key : $value
508

    
509
Step 4
510
------
511
Save the changes you have just performed. Editing a live style will immediately
512
affect the site for your visitors and will also overwrite the draft version of the style.
513

    
514
Type "y" to continue, "n" to abort.
515
';
516

    
517
  return dt($warning);
518
}