function sheetnode_plugin_style::render_sheet in Sheetnode 7
Same name and namespace in other branches
- 6 views/sheetnode_plugin_style.inc \sheetnode_plugin_style::render_sheet()
- 7.2 views/sheetnode_plugin_style.inc \sheetnode_plugin_style::render_sheet()
3 calls to sheetnode_plugin_style::render_sheet()
- sheetnode_phpexcel_plugin_style::render in modules/
sheetnode_phpexcel/ sheetnode_phpexcel_plugin_style.inc - Render the display in this style.
- sheetnode_plugin_style::render in views/
sheetnode_plugin_style.inc - Render the display in this style.
- sheetnode_raw_plugin_style::render in views/
sheetnode_raw_plugin_style.inc - Render the display in this style.
File
- views/
sheetnode_plugin_style.inc, line 58
Class
Code
function render_sheet() {
$tangent = $this->options['expansion'];
$normal = 1 - $tangent;
if ($this->options['use_template']) {
$socialcalc = socialcalc_parse($this->options['template']);
$lastpos = array(
0,
0,
);
// Iterate through cells, gathering placeholder values.
if (!empty($socialcalc['sheet']['cells'])) {
foreach ($socialcalc['sheet']['cells'] as $coord => $cell) {
// Field placeholder?
$matches = array();
if (isset($cell['datavalue']) && $cell['datatype'] == 't') {
if (preg_match('/^\\${(.*?)\\}$/', $cell['datavalue'], $matches)) {
$field_name = $this
->find_field($matches[1]);
if (isset($cell['comment']) && preg_match('/^\\${(.*?)\\}$/', $cell['comment'], $comment_matches)) {
$comment_field_name = $this
->find_field($comment_matches[1]);
}
else {
$comment_field_name = FALSE;
}
if ($field_name && !$this->view->field[$field_name]->options['exclude']) {
// it's a field expansion
$fields[$field_name] = array(
'coord' => $coord,
'cell' => $cell,
'info' => $this->view->field[$field_name],
'comment' => $comment_field_name,
);
}
else {
// it's a formula expansion
$formula_expansions[] = array(
'coord' => $coord,
'cell' => $cell,
'expression' => $matches[1],
'comment' => $comment_field_name,
);
}
}
else {
if (preg_match('/^\\$\\[(.*?)]$/', $cell['datavalue'], $matches)) {
// it's a formula placement
$formulas[] = array(
'coord' => $coord,
'cell' => $cell,
'expression' => $matches[1],
);
}
}
}
$lastpos = array(
max($lastpos[0], $cell['pos'][0]),
max($lastpos[1], $cell['pos'][1]),
);
}
}
// Replace field placeholders with actual values.
$tangent_increment = array(
SHEETNODE_EXPANSION_VERTICAL => 0,
SHEETNODE_EXPANSION_HORIZONTAL => 1,
);
if (!empty($fields)) {
foreach ($fields as $field_name => $field) {
unset($socialcalc['sheet']['cells'][$field['coord']]);
$newcell = $field['cell'];
$pos = $maxpos = $newcell['pos'];
$this->view->row_index = 0;
foreach ($this->view->result as $j => $result) {
$this->view->row_index = $j;
// Get comment value if any.
if ($field['comment']) {
$comment_field = $this->view->field[$field['comment']];
$newcell['comment'] = strip_tags($comment_field
->theme($result));
}
// Get cell value.
$value = $field['info']
->theme($result);
if (is_array($value)) {
// Expand an array of values into consecutive cells.
$itempos = $pos;
foreach ($value as $item) {
$itemcell = $newcell;
$itemcell['pos'] = $itempos;
$itemcell['datavalue'] = $item;
$itemcell['datatype'] = is_numeric($item) ? 'v' : 't';
$itemcell['valuetype'] = is_numeric($item) ? 'n' : 'th';
$newcells[socialcalc_cr_to_coord($itempos[0], $itempos[1])] = $itemcell;
$itempos[$tangent]++;
$maxpos[$tangent] = max($maxpos[$tangent], $itempos[$tangent]);
}
}
else {
// Expand a single value into the current cell.
$newcell['pos'] = $pos;
$newcell['datavalue'] = $value;
$newcell['datatype'] = is_numeric($value) ? 'v' : 't';
$newcell['valuetype'] = is_numeric($value) ? 'n' : 'th';
$newcells[socialcalc_cr_to_coord($pos[0], $pos[1])] = $newcell;
}
$pos[$normal]++;
}
$maxpos[$normal] = $pos[$normal];
$fields[$field_name]['endpos'] = array(
$maxpos[0] - $tangent_increment[$tangent],
$maxpos[1] - $tangent_increment[$normal],
);
$lastpos = array(
max($lastpos[0], $maxpos[0]),
max($lastpos[1], $maxpos[1]),
);
}
}
// Replace formula expansions with actual values.
if (!empty($formula_expansions) && !empty($fields)) {
foreach ($formula_expansions as $fe) {
unset($socialcalc['sheet']['cells'][$fe['coord']]);
$newcell = $fe['cell'];
$pos = $newcell['pos'];
$matches = array();
$count = preg_match_all('/@(.*?)@|\\$(.*?)\\$/', $fe['expression'], $matches);
$this->view->row_index = 0;
foreach ($this->view->result as $j => $result) {
$this->view->row_index = $j;
// Get comment value if any.
if ($fe['comment']) {
$comment_field = $this->view->field[$fe['comment']];
$newcell['comment'] = strip_tags($comment_field
->theme($result));
}
// Expand formula.
$expression = $fe['expression'];
$newcell['pos'] = $pos;
for ($i = 0; $i < $count; $i++) {
$replace = NULL;
$match = !empty($matches[1][$i]) ? $matches[1][$i] : $matches[2][$i];
$field_name = $this
->find_field($match);
if (!$field_name) {
// Not a field: try a cell coordinate.
if (preg_match('/^\\$?\\w\\w?\\$?\\d+$/', $match)) {
$refpos = socialcalc_coord_to_cr($match);
foreach ($fields as $field) {
if ($refpos == $field['cell']['pos']) {
$replace = socialcalc_cr_to_coord($field['cell']['pos'][0] + $j * $tangent_increment[$tangent], $field['cell']['pos'][1] + $j * $tangent_increment[$normal]);
break;
}
}
}
}
else {
if ($matches[0][$i][0] == '@' && isset($fields[$field_name])) {
$replace = socialcalc_cr_to_coord($fields[$field_name]['cell']['pos'][0] + $j * $tangent_increment[$tangent], $fields[$field_name]['cell']['pos'][1] + $j * $tangent_increment[$normal]);
}
else {
if ($matches[0][$i][0] == '$') {
$field = $this->view->field[$field_name];
$replace = $field
->get_value($result);
// Special case: empty array == NULL.
if (is_array($replace) && empty($replace)) {
$replace = NULL;
}
else {
if (!is_scalar($replace) && isset($field->field_info) && isset($result->_field_data[$field->field_alias])) {
$field_data = $result->_field_data[$field->field_alias];
$output = '';
foreach ($replace as $item) {
$element = field_view_value($field_data['entity_type'], $field_data['entity'], $field_name, $item);
$output .= drupal_render($element);
}
$replace = $output;
}
}
}
}
}
if (!is_null($replace)) {
$expression = str_replace($matches[0][$i], $replace, $expression);
}
else {
$expression = NULL;
}
}
if (!is_null($expression)) {
$newcell['formula'] = $expression;
$newcell['datatype'] = 'f';
$newcell['valuetype'] = 'n';
$newcell['datavalue'] = 0;
$newcells[socialcalc_cr_to_coord($pos[0], $pos[1])] = $newcell;
}
$pos[$normal]++;
}
$fields[] = array(
'cell' => $fe['cell'],
'coord' => $fe['coord'],
'endpos' => array(
$pos[0] - $tangent_increment[$tangent],
$pos[1] - $tangent_increment[$normal],
),
);
$lastpos = array(
max($lastpos[0], $pos[0]),
max($lastpos[1], $pos[1]),
);
}
}
// Replace formula placeholders with actual values.
if (!empty($formulas)) {
foreach ($formulas as $formula) {
$newcell = $formula['cell'];
$expression = $formula['expression'];
$matches = array();
$count = (int) preg_match_all('/@(.*?)@/', $expression, $matches);
for ($i = 0; $i < $count; $i++) {
$field_name = $this
->find_field($matches[1][$i]);
if (!$field_name || !isset($fields[$field_name])) {
// Not a field: try a cell coordinate.
if (preg_match('/^\\$?\\w\\w?\\$?\\d+$/', $matches[1][$i])) {
$replace = '@' . $matches[1][$i] . '@';
$references[$formula['coord']][] = socialcalc_coord_to_cr(str_replace('$', '', $matches[1][$i]));
}
else {
$replace = NULL;
}
}
else {
$field = $fields[$field_name];
$replace = socialcalc_cr_to_coord($field['cell']['pos'][0], $field['cell']['pos'][1]) . ':' . socialcalc_cr_to_coord($field['endpos'][0], $field['endpos'][1]);
}
if (!is_null($replace)) {
$expression = str_replace($matches[0][$i], $replace, $expression);
}
else {
$expression = NULL;
}
}
if (!is_null($expression)) {
$newcell['formula'] = $expression;
$newcell['datatype'] = 'f';
$newcell['valuetype'] = 'n';
$newcell['datavalue'] = 0;
$socialcalc['sheet']['cells'][$formula['coord']] = $newcell;
}
}
}
// Adjust positions of all cells based on expanded values.
if (!empty($fields)) {
foreach ($socialcalc['sheet']['cells'] as $coord => $cell) {
$pos = $cell['pos'];
foreach ($fields as $field) {
if ($pos[$tangent] == $field['cell']['pos'][$tangent] && $pos[$normal] > $field['cell']['pos'][$normal]) {
$pos[$normal] += $field['endpos'][$normal] - $field['cell']['pos'][$normal];
unset($socialcalc['sheet']['cells'][$coord]);
$cell['pos'] = $pos;
$newcoord = socialcalc_cr_to_coord($pos[0], $pos[1]);
$socialcalc['sheet']['cells'][$newcoord] = $cell;
if (isset($references[$coord])) {
$references[$newcoord] = $references[$coord];
unset($references[$coord]);
}
$lastpos = array(
max($lastpos[0], $pos[0]),
max($lastpos[1], $pos[1]),
);
break;
}
}
}
}
// Adjust references in formulas based on expanded values.
if (!empty($fields) && !empty($references)) {
foreach ($references as $coord => $positions) {
$cell = $socialcalc['sheet']['cells'][$coord];
$expression = $cell['formula'];
$matches = array();
$count = (int) preg_match_all('/@\\$?\\w\\w?\\$?\\d+@/', $expression, $matches);
for ($i = 0; $i < $count; $i++) {
$pos = $positions[$i];
foreach ($fields as $field) {
if ($pos[$tangent] == $field['cell']['pos'][$tangent]) {
if ($pos[$normal] == $field['cell']['pos'][$normal]) {
// referencing a field cell
$refrange = socialcalc_cr_to_coord($field['cell']['pos'][0], $field['cell']['pos'][1]) . ':' . socialcalc_cr_to_coord($field['endpos'][0], $field['endpos'][1]);
$expression = str_replace($matches[0][$i], $refrange, $expression);
break;
}
else {
if ($pos[$normal] > $field['cell']['pos'][$normal]) {
// referencing a cell below a field
$pos[$normal] += $field['endpos'][$normal] - $field['cell']['pos'][$normal];
$refcoord = socialcalc_cr_to_coord($pos[0], $pos[1], TRUE);
$expression = preg_replace('/@(\\$?)\\w\\w?(\\$?)\\d+@/', '${1}' . $refcoord[0] . '${2}' . $refcoord[1], $expression, 1);
break;
}
}
}
}
}
$cell['formula'] = $expression;
$socialcalc['sheet']['cells'][$coord] = $cell;
}
}
// Replace values inside the sheet.
if (!empty($newcells)) {
$socialcalc['sheet']['cells'] += $newcells;
}
$socialcalc['sheet']['attribs']['lastcol'] = $lastpos[0];
$socialcalc['sheet']['attribs']['lastrow'] = $lastpos[1];
// Adjust starting cell in editor.
$pos = $socialcalc['edit']['ecell']['pos'];
if (!empty($fields)) {
foreach ($fields as $field) {
if ($pos[$tangent] == $field['cell']['pos'][$tangent] && $pos[$normal] > $field['cell']['pos'][$normal]) {
$pos[$normal] += $field['endpos'][$normal] - $field['cell']['pos'][$normal];
$ecell_changed = TRUE;
break;
}
}
}
$socialcalc['edit']['ecell']['pos'] = $pos;
$socialcalc['edit']['ecell']['coord'] = socialcalc_cr_to_coord($pos[0], $pos[1]);
// Adjust row and column panes.
$panes = $tangent == SHEETNODE_EXPANSION_VERTICAL ? 'rowpanes' : 'colpanes';
foreach ($socialcalc['edit'][$panes] as $i => $pane) {
$delta = 0;
if (!empty($fields)) {
foreach ($fields as $field) {
if ($pane['last'] > $field['cell']['pos'][$normal]) {
$delta = max($delta, $field['endpos'][$normal] - $field['cell']['pos'][$normal]);
}
}
}
if (!empty($ecell_changed)) {
$socialcalc['edit'][$panes][$i]['first'] += $delta;
$socialcalc['edit'][$panes][$i]['last'] += $delta;
}
}
}
else {
// Hand-make default SocialCalc structure based on views results.
$pos = array(
1,
1,
);
foreach ($this->view->field as $field => $info) {
if ($info->options['exclude']) {
continue;
}
$cell['pos'] = $pos;
$cell['datavalue'] = $info
->label();
$cell['datatype'] = 't';
$cell['valuetype'] = 't';
$sheet['cells'][socialcalc_cr_to_coord($pos[0], $pos[1])] = $cell;
$pos[$tangent]++;
}
$pos[$normal] = 2;
$this->view->row_index = 0;
foreach ($this->view->result as $j => $result) {
$this->view->row_index = $j;
$pos[$tangent] = 1;
foreach ($this->view->field as $field => $info) {
if ($info->options['exclude']) {
continue;
}
$value = $info
->theme($result);
if (is_array($value)) {
foreach ($value as $item) {
$cell['pos'] = $pos;
$cell['datavalue'] = $item;
$cell['datatype'] = is_numeric($item) ? 'v' : 't';
$cell['valuetype'] = is_numeric($item) ? 'n' : 'th';
$sheet['cells'][socialcalc_cr_to_coord($pos[0], $pos[1])] = $cell;
$pos[$tangent]++;
}
}
else {
$cell['pos'] = $pos;
$cell['datavalue'] = $value;
$cell['datatype'] = is_numeric($value) ? 'v' : 't';
$cell['valuetype'] = is_numeric($value) ? 'n' : 'th';
$sheet['cells'][socialcalc_cr_to_coord($pos[0], $pos[1])] = $cell;
$pos[$tangent]++;
}
}
$pos[$normal]++;
}
$sheet['attribs']['lastcol'] = $pos[0] - 1;
$sheet['attribs']['lastrow'] = $pos[1] - 1;
if ($tangent == SHEETNODE_EXPANSION_VERTICAL) {
$edit['rowpanes'] = array(
0 => array(
'first' => 1,
'last' => 1,
),
1 => array(
'first' => 2,
'last' => $sheet['attribs']['lastrow'],
),
);
$edit['colpanes'] = array(
0 => array(
'first' => 1,
'last' => $sheet['attribs']['lastcol'],
),
);
}
else {
$edit['colpanes'] = array(
0 => array(
'first' => 1,
'last' => 1,
),
1 => array(
'first' => 2,
'last' => $sheet['attribs']['lastcol'],
),
);
$edit['rowpanes'] = array(
0 => array(
'first' => 1,
'last' => $sheet['attribs']['lastrow'],
),
);
}
$edit['ecell'] = array(
'coord' => 'A1',
);
// Inject the Sheetnode code.
$socialcalc = array(
'sheet' => $sheet,
'edit' => $edit,
'audit' => socialcalc_default_audit($sheet),
);
}
// Merge with saved version if any.
$this
->merge_annotation($socialcalc);
unset($this->view->row_index);
return $socialcalc;
}