| 1 |
<?php |
<?php |
| 2 |
// $Id: views_customfield.module,v 1.1 2008/10/30 16:04:56 casey Exp $ |
// $Id: views_customfield.module,v 1.2 2008/10/30 18:45:23 casey Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* Implementation of hook_views_tables() |
* Implementation of hook_views_tables() |
| 7 |
* @return array |
* @return array |
| 8 |
*/ |
*/ |
| 9 |
function views_customfield_views_tables() { |
function views_customfield_views_tables() { |
|
|
|
| 10 |
$tables['views_customfield'] = array( |
$tables['views_customfield'] = array( |
| 11 |
'fields' => array( |
'fields' => array( |
| 12 |
'text' => array( |
'text' => array( |
| 15 |
'sortable' => FALSE, |
'sortable' => FALSE, |
| 16 |
'notafield' => TRUE, |
'notafield' => TRUE, |
| 17 |
'handler' => 'views_customfield_text_field_handler', |
'handler' => 'views_customfield_text_field_handler', |
|
'validate' => 'views_customfield_text_field_validate', |
|
| 18 |
/** |
/** |
| 19 |
* @see http://drupal.org/node/99792#option (complex option fields) |
* @see http://drupal.org/node/99792#option (complex option fields) |
| 20 |
*/ |
*/ |
| 38 |
) |
) |
| 39 |
) |
) |
| 40 |
); |
); |
| 41 |
|
|
| 42 |
|
if (module_exists('validator_phpcode')) { |
| 43 |
|
$tables['views_customfield']['fields']['text']['validate'] = 'views_customfield_text_field_validate'; |
| 44 |
|
} |
| 45 |
|
|
| 46 |
return $tables; |
return $tables; |
| 47 |
} |
} |
| 61 |
$options = unserialize($fielddata['options']); |
$options = unserialize($fielddata['options']); |
| 62 |
$code = $options['value']; |
$code = $options['value']; |
| 63 |
|
|
| 64 |
if (($error = _views_customfield_php_has_errors($code))) { |
if (($error = validator_phpcode_has_errors($code))) { |
| 65 |
// TODO not very efficient, but $fielddata doesn't contain position-info |
// TODO not very efficient, but $fielddata doesn't contain position-info |
| 66 |
|
// Some other way possible? |
| 67 |
for ($i=0;$i<$view['field']['count'];$i++) { |
for ($i=0;$i<$view['field']['count'];$i++) { |
| 68 |
if ($form['field'][$i]['fullname']['#value'] == 'views_customfield.text') { |
if ($form['field'][$i]['fullname']['#value'] == 'views_customfield.text' |
| 69 |
if ($form['field'][$i]['options']['value']['#value'] == $code) { |
&& $form['field'][$i]['options']['value']['#value'] == $code) { |
| 70 |
$msg = t('Views Custom field') .': '. $error[0] .' on line '. $error[1]; |
$msg = t('Views Custom field') .': '. $error[0] .' on line '. $error[1]; |
| 71 |
form_error($form['field'][$i]['options']['value'], $msg); |
form_error($form['field'][$i]['options']['value'], $msg); |
| 72 |
return; |
return; |
|
} |
|
| 73 |
} |
} |
| 74 |
} |
} |
| 75 |
} |
} |
| 86 |
*/ |
*/ |
| 87 |
function views_customfield_text_field_handler($fieldinfo, $fielddata, $value, $data) { |
function views_customfield_text_field_handler($fieldinfo, $fielddata, $value, $data) { |
| 88 |
static $static; |
static $static; |
| 89 |
|
// TODO should be possible to unserialize just once per view/field |
| 90 |
$options = unserialize($fielddata['options']); |
$options = unserialize($fielddata['options']); |
| 91 |
|
|
| 92 |
return _views_customfield_eval($options['value'], $static[$fielddata['position']], $data); |
return _views_customfield_eval($options['value'], $static[$fielddata['position']], $data); |
| 171 |
return '</td><td colspan="7"></td></tr><tr><td colspan="4">'.$element['#children']; |
return '</td><td colspan="7"></td></tr><tr><td colspan="4">'.$element['#children']; |
| 172 |
} |
} |
| 173 |
|
|
|
/** |
|
|
* Returns FALSE if there is no syntax error in $code, or an array($message, $line) |
|
|
* if there is one. |
|
|
* |
|
|
* @see http://us2.php.net/manual/en/function.php-check-syntax.php#86466 |
|
|
* @author nicolas dot grekas+php at gmail dot com |
|
|
* |
|
|
* @param string $code |
|
|
* @return mixed |
|
|
* FALSE if $code has no PHP errors, else: |
|
|
* array |
|
|
* '0' string contains the error message |
|
|
* '1' int contains the line number the error was raised at |
|
|
*/ |
|
|
function _views_customfield_php_has_errors($code) { |
|
|
$braces = 0; |
|
|
$inString = 0; |
|
|
|
|
|
// First of all, we need to know if braces are correctly balanced. |
|
|
// This is not trivial due to variable interpolation which |
|
|
// occurs in heredoc, backticked and double quoted strings |
|
|
foreach (token_get_all('<?php ' . $code) as $token) { |
|
|
if (is_array($token)) { |
|
|
switch ($token[0]) { |
|
|
case T_CURLY_OPEN: |
|
|
case T_DOLLAR_OPEN_CURLY_BRACES: |
|
|
case T_START_HEREDOC: ++$inString; break; |
|
|
case T_END_HEREDOC: --$inString; break; |
|
|
} |
|
|
} |
|
|
else if ($inString & 1) { |
|
|
switch ($token) { |
|
|
case '`': |
|
|
case '"': --$inString; break; |
|
|
} |
|
|
} |
|
|
else { |
|
|
switch ($token) { |
|
|
case '`': |
|
|
case '"': ++$inString; break; |
|
|
|
|
|
case '{': ++$braces; break; |
|
|
case '}': |
|
|
if ($inString) --$inString; |
|
|
else { |
|
|
--$braces; |
|
|
if ($braces < 0) break 2; |
|
|
} |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
// Display parse error messages and use output buffering to catch them |
|
|
$inString = @ini_set('log_errors', FALSE); |
|
|
$token = @ini_set('display_errors', TRUE); |
|
|
ob_start(); |
|
|
// If $braces is not zero, then we are sure that $code is broken. |
|
|
// We run it anyway in order to catch the error message and line number. |
|
|
|
|
|
// Else, if $braces are correctly balanced, then we can safely put |
|
|
// $code in a dead code sandbox to prevent its execution. |
|
|
// Note that without this sandbox, a function or class declaration inside |
|
|
// $code could throw a "Cannot redeclare" fatal error. |
|
|
$braces || $code = "if(0){{$code}\n}"; |
|
|
|
|
|
if (FALSE === eval('?>'. $code)) { |
|
|
if ($braces) $braces = PHP_INT_MAX; |
|
|
else { |
|
|
// Get the maximum number of lines in $code to fix a border case |
|
|
FALSE !== strpos($code, "\r") && $code = strtr(str_replace("\r\n", "\n", $code), "\r", "\n"); |
|
|
$braces = substr_count($code, "\n"); |
|
|
} |
|
|
|
|
|
$code = ob_get_clean(); |
|
|
$code = strip_tags($code); |
|
|
|
|
|
// Get the error message and line number |
|
|
if (preg_match("'syntax error, (.+) in .+ on line (\d+)$'s", $code, $code)) { |
|
|
$code[2] = (int) $code[2]; |
|
|
$code = $code[2] <= $braces |
|
|
? array($code[1], (int) $code[2]) |
|
|
: array('unexpected $end' . substr($code[1], 14), $braces); |
|
|
} |
|
|
else $code = array('syntax error', 0); |
|
|
} |
|
|
else { |
|
|
ob_end_clean(); |
|
|
$code = FALSE; |
|
|
} |
|
|
|
|
|
@ini_set('display_errors', $token); |
|
|
@ini_set('log_errors', $inString); |
|
|
|
|
|
return $code; |
|
|
} |
|