Store the footer caption BIFF record.

@access private
11397
function _storeFooter()
    {
        $record  = 0x0015;               // Record identifier

        $str      = $this->_footer;       // Footer string
        $cch      = strlen($str);         // Length of footer string
        if ($this->_BIFF_version == 0x0600) {
            $encoding = 0x0;                  // TODO: Unicode support
            $length   = 3 + $cch;             // Bytes to follow
        } else {
            $length  = 1 + $cch;
        }

        $header    = pack("vv", $record, $length);
        if ($this->_BIFF_version == 0x0600) {
            $data      = pack("vC",  $cch, $encoding);
        } else {
            $data      = pack("C",  $cch);
        }

        $this->_prepend($header . $data . $str);
    }
1143309
private function _writeMarginBottom()
	{
		$record  = 0x0029;				   // Record identifier
		$length  = 0x0008;				   // Bytes to follow

		$margin  = $this->_phpSheet->getPageMargins()->getBottom();	 // Margin in inches

		$header	= pack("vv",  $record, $length);
		$data	  = pack("d",   $margin);
		if (self::getByteOrder()) { // if it's Big Endian
			$data = strrev($data);
		}

		$this->_append($header . $data);
	}
272318
function _storeHeader()
    {
        $record  = 0x0014;               // Record identifier

        $str      = $this->_header;       // header string
        $cch      = strlen($str);         // Length of header string
        if ($this->_BIFF_version == 0x0600) {
            $encoding = 0x0;                  // TODO: Unicode support
            $length   = 3 + $cch;             // Bytes to follow
        } else {
            $length  = 1 + $cch;             // Bytes to follow
        }

        $header   = pack("vv", $record, $length);
        if ($this->_BIFF_version == 0x0600) {
            $data     = pack("vC",  $cch, $encoding);
        } else {
            $data      = pack("C",  $cch);
        }

        $this->_prepend($header.$data.$str);
    }
1204375
private function footer()
    {
        $footer = $this->footer_content;
        if ($footer) {
            if ($this->header_type == self::OPT_HEADER_PRE) {
                $footer = str_replace("\n", '', $footer);;
            }
            $footer = $this->replace_keywords($footer);

            if ($this->use_classes) {
                $attr = ' class="foot"';
            }
            else {
                $attr = " style=\"{$this->footer_content_style}\"";
            }
            if ($this->header_type == self::OPT_HEADER_PRE_TABLE && $this->line_numbers != self::OPT_LINE_NUMBERS_NONE) {
                $footer = "<tfoot><tr><td colspan=\"2\">$footer</td></tr></tfoot>";
            }
            else {
                $footer = "<div$attr>$footer</div>";
            }
        }

        if (self::OPT_HEADER_NONE == $this->header_type) {
            return ($this->line_numbers != self::OPT_LINE_NUMBERS_NONE) ? '</ol>' . $footer : $footer;
        }

        if ($this->header_type == self::OPT_HEADER_DIV || $this->header_type == self::OPT_HEADER_PRE_VALID) {
            if ($this->line_numbers != self::OPT_LINE_NUMBERS_NONE) {
                return "</ol>$footer</div>";
            }

            return ($this->force_code_block ? '</div>' : '') .
                   "$footer</div>";
        }
        elseif ($this->header_type == self::OPT_HEADER_PRE_TABLE) {
            if ($this->line_numbers != self::OPT_LINE_NUMBERS_NONE) {
                return "</tr></tbody>$footer</table>";
            }

            return ($this->force_code_block ? '</div>' : '') .
                   "$footer</div>";
        }
        else {
            if ($this->line_numbers != self::OPT_LINE_NUMBERS_NONE) {
                return "</ol>$footer</pre>";
            }

            return ($this->force_code_block ? '</div>' : '') .
                   "$footer</pre>";
        }
    }
833802
function _storeDefcol()
    {
        $record   = 0x0055;      // Record identifier
        $length   = 0x0002;      // Number of bytes to follow
        $colwidth = 0x0008;      // Default column width

        $header   = pack("vv", $record, $length);
        $data     = pack("v",  $colwidth);
        $this->_prepend($header . $data);
    }
247254
private function _writeMarginTop()
	{
		$record  = 0x0028;				   // Record identifier
		$length  = 0x0008;				   // Bytes to follow

		$margin  = $this->_phpSheet->getPageMargins()->getTop();	 // Margin in inches

		$header	= pack("vv",  $record, $length);
		$data	  = pack("d",   $margin);
		if (self::getByteOrder()) { // if it's Big Endian
			$data = strrev($data);
		}

		$this->_append($header . $data);
	}
642353
function _storeDataValidity()
    {
        $record      = 0x01b2;      // Record identifier
        $length      = 0x0012;      // Bytes to follow

        $grbit       = 0x0002;      // Prompt box at cell, no cached validity data at DV records
        $horPos      = 0x00000000;  // Horizontal position of prompt box, if fixed position
        $verPos      = 0x00000000;  // Vertical position of prompt box, if fixed position
        $objId       = 0xffffffff;  // Object identifier of drop down arrow object, or -1 if not visible

        $header      = pack('vv', $record, $length);
        $data        = pack('vVVVV', $grbit, $horPos, $verPos, $objId,
                                     count($this->_dv));
        $this->_append($header.$data);

        $record = 0x01be;              // Record identifier
        foreach ($this->_dv as $dv) {
            $length = strlen($dv);      // Bytes to follow
            $header = pack("vv", $record, $length);
            $this->_append($header . $dv);
        }
    }
1321320
private function readTopMargin()
    {
        $length = self::getInt2d($this->data, $this->pos + 2);
        $recordData = $this->readRecordData($this->data, $this->pos + 4, $length);

        // move stream pointer to next record
        $this->pos += 4 + $length;

        if (!$this->readDataOnly) {
            // offset: 0; size: 8
            $this->phpSheet->getPageMargins()->setTop(self::extractNumber($recordData));
        }
    }
563007
def records(self):
        """"""
        caption_records = self.caption.records
        # Parse headers to extract contextual data and determine value parser for the column
        value_parsers = {}
        header_compounds = defaultdict(list)
        table_records = ModelList()
        seen_compound_col = False
        log.debug('Parsing table headers')

        for i, col_headings in enumerate(zip(*self.headings)):
            # log.info('Considering column %s' % i)
            for parsers in self.parsers:
                log.debug(parsers)
                heading_parser = parsers[0]
                value_parser = parsers[1] if len(parsers) > 1 else None
                disallowed_parser = parsers[2] if len(parsers) > 2 else None
                allowed = False
                disallowed = False
                for cell in col_headings:
                    log.debug(cell.tagged_tokens)
                    results = list(heading_parser.parse(cell.tagged_tokens))
                    if results:
                        allowed = True
                        log.debug('Heading column %s: Match %s: %s' % (i, heading_parser.__class__.__name__, [c.serialize() for c in results]))
                    # Results from every parser are stored as header compounds
                    header_compounds[i].extend(results)
                    # Referenced footnote records are also stored
                    for footnote in self.footnotes:
                        # print('%s - %s - %s' % (footnote.id, cell.references, footnote.id in cell.references))
                        if footnote.id in cell.references:
                            log.debug('Adding footnote %s to column %s: %s' % (footnote.id, i, [c.serialize() for c in footnote.records]))
                            # print('Footnote records: %s' % [c.to_primitive() for c in footnote.records])
                            header_compounds[i].extend(footnote.records)
                    # Check if the disallowed parser matches this cell
                    if disallowed_parser and list(disallowed_parser.parse(cell.tagged_tokens)):
                        log.debug('Column %s: Disallowed %s' % (i, heading_parser.__class__.__name__))
                        disallowed = True
                # If heading parser matches and disallowed parser doesn't, store the value parser
                if allowed and not disallowed and value_parser and i not in value_parsers:
                    if isinstance(value_parser, CompoundCellParser):
                        # Only take the first compound col
                        if seen_compound_col:
                            continue
                        seen_compound_col = True
                    log.debug('Column %s: Value parser: %s' % (i, value_parser.__class__.__name__))
                    value_parsers[i] = value_parser
                    # Stop after value parser is assigned?

        # for hrow in self.headings:
        #     for i, cell in enumerate(hrow):
        #         log.debug(cell.tagged_tokens)
        #         for heading_parser, value_parser in self.parsers:
        #             results = list(heading_parser.parse(cell.tagged_tokens))
        #             if results:
        #                 log.debug('Heading column %s: Match %s: %s' % (i, heading_parser.__class__.__name__, [c.to_primitive() for c in results]))
        #             # Results from every parser are stored as header compounds
        #             header_compounds[i].extend(results)
        #             if results and value_parser and i not in value_parsers:
        #                 if isinstance(value_parser, CompoundCellParser):
        #                     # Only take the first compound col
        #                     if seen_compound_col:
        #                         continue
        #                     seen_compound_col = True
        #                 value_parsers[i] = value_parser
        #                 break  # Stop after first heading parser matches
        #         # Referenced footnote records are also stored
        #         for footnote in self.footnotes:
        #             # print('%s - %s - %s' % (footnote.id, cell.references, footnote.id in cell.references))
        #             if footnote.id in cell.references:
        #                 log.debug('Adding footnote %s to column %s: %s' % (footnote.id, i, [c.to_primitive() for c in footnote.records]))
        #                 # print('Footnote records: %s' % [c.to_primitive() for c in footnote.records])
        #                 header_compounds[i].extend(footnote.records)

        # If no parsers, skip processing table
        if value_parsers:

            # If no CompoundCellParser() in value_parsers and value_parsers[0] == [] then set CompoundCellParser()
            if not seen_compound_col and 0 not in value_parsers:
                log.debug('No compound column found in table, assuming first column')
                value_parsers[0] = CompoundCellParser()

            for row in self.rows:
                row_compound = Compound()
                # Keep cell records that are contextual to merge at the end
                contextual_cell_compounds = []
                for i, cell in enumerate(row):
                    log.debug(cell.tagged_tokens)
                    if i in value_parsers:
                        results = list(value_parsers[i].parse(cell.tagged_tokens))
                        if results:
                            log.debug('Cell column %s: Match %s: %s' % (i, value_parsers[i].__class__.__name__, [c.serialize() for c in results]))
                        # For each result, merge in values from elsewhere
                        for result in results:
                            # Merge each header_compounds[i]
                            for header_compound in header_compounds[i]:
                                if header_compound.is_contextual:
                                    result.merge_contextual(header_compound)
                            # Merge footnote compounds
                            for footnote in self.footnotes:
                                if footnote.id in cell.references:
                                    for footnote_compound in footnote.records:
                                        result.merge_contextual(footnote_compound)
                            if result.is_contextual:
                                # Don't merge cell as a value compound if there are no values
                                contextual_cell_compounds.append(result)
                            else:
                                row_compound.merge(result)
                # Merge contextual information from cells
                for contextual_cell_compound in contextual_cell_compounds:
                    row_compound.merge_contextual(contextual_cell_compound)
                # If no compound name/label, try take from previous row
                if not row_compound.names and not row_compound.labels and table_records:
                    prev = table_records[-1]
                    row_compound.names = prev.names
                    row_compound.labels = prev.labels
                # Merge contextual information from caption into the full row
                for caption_compound in caption_records:
                    if caption_compound.is_contextual:
                        row_compound.merge_contextual(caption_compound)
                # And also merge from any footnotes that are referenced from the caption
                for footnote in self.footnotes:
                    if footnote.id in self.caption.references:
                        # print('Footnote records: %s' % [c.to_primitive() for c in footnote.records])
                        for fn_compound in footnote.records:
                            row_compound.merge_contextual(fn_compound)

                log.debug(row_compound.serialize())
                if row_compound.serialize():
                    table_records.append(row_compound)

        # TODO: If no rows have name or label, see if one is in the caption

        # Include non-contextual caption records in the final output
        caption_records = [c for c in caption_records if not c.is_contextual]
        table_records += caption_records
        return table_records
30146
public function Footer()
    {
        // prepare the text from the tranlated text
        $txt = '';
        if ($this->_footerParam['form']) {
            $txt = Locale::get('pdf05');
        }
        if ($this->_footerParam['date'] && $this->_footerParam['time']) {
            $txt.= ($txt ? ' - ' : '').Locale::get('pdf03');
        }
        if ($this->_footerParam['date'] && !$this->_footerParam['time']) {
            $txt.= ($txt ? ' - ' : '').Locale::get('pdf01');
        }
        if (!$this->_footerParam['date'] && $this->_footerParam['time']) {
            $txt.= ($txt ? ' - ' : '').Locale::get('pdf02');
        }
        if ($this->_footerParam['page']) {
            $txt.= ($txt ? ' - ' : '').Locale::get('pdf04');
        }

        if (strlen($txt)>0) {
            // replace some values
            $toReplace = array(
                '[[date_d]]'  => date('d'),
                '[[date_m]]'  => date('m'),
                '[[date_y]]'  => date('Y'),
                '[[date_h]]'  => date('H'),
                '[[date_i]]'  => date('i'),
                '[[date_s]]'  => date('s'),
                '[[page_cu]]' => $this->getMyNumPage(),
                '[[page_nb]]' => $this->getMyAliasNbPages(),
            );
            $txt = str_replace(array_keys($toReplace), array_values($toReplace), $txt);

            // draw the footer
            parent::SetY(-11);
            $this->SetFont('helvetica', 'I', 8);
            $this->Cell(0, 10, $txt, 0, 0, 'R');
        }
    }
519159
public function footer()
    {
        $this->output->write($this->color('success', sprintf("\n  %d passing", $this->passing)));
        $this->output->writeln(sprintf($this->color('muted', " (%s)"), \PHP_Timer::secondsToTimeString($this->getTime())));
        if (! empty($this->errors)) {
            $this->output->writeln($this->color('error', sprintf("  %d failing", count($this->errors))));
        }
        if ($this->pending) {
            $this->output->writeln($this->color('pending', sprintf("  %d pending", $this->pending)));
        }
        $this->output->writeln("");
        $errorCount = count($this->errors);
        for ($i = 0; $i < $errorCount; $i++) {
            list($test, $error) = $this->errors[$i];
            $this->outputError($i + 1, $test, $error);
            $this->output->writeln('');
        }
    }
1242260
public function initFileActiveRecord()
    {
        if (count(static::primaryKey()) === 1) {
            $this->on(self::EVENT_BEFORE_INSERT, function ($event) {
                if (empty($event->sender->{$event->data['pkName']})) {
                    /** @var ActiveRecord $className */
                    $className = $event->data['className'];
                    $lastModel = $className::find()->orderBy([$event->data['pkName'] => SORT_DESC])->one();
                    $event->sender->{$event->data['pkName']} = $lastModel !== null ? $lastModel->{$event->data['pkName']} + 1 : 1;
                }
            }, ['pkName' => static::primaryKey()[0], 'className' => static::class]);
        }
    }
547167
public function doAfter() {
        if ($this->_footerController) {
            $viewPath = ROOT . DS . 'app' . DS . 'views' . DS .
                strtolower($this->_controller->getControllerName()) . DS .
                strtolower($this->_controller->getAction()) . DS . 'footer.php';
            if (file_exists($viewPath)) {
                $this->_controller->addView(FView::create(strtolower($this->_controller->getControllerName()) . DS .
                    strtolower($this->_controller->getAction()) . DS . 'footer.php', $this->getController()->getApp()));
            } elseif ($this->_footerGlobal) {
                $viewPath = ROOT . DS . 'app' . DS . 'views' . DS . 'footer.php';
                if (file_exists($viewPath)) {
                    $this->_controller->addView(FView::create('footer.php', $this->getController()->getApp()));
                }
            }
        }
    }
1016218
private function _saveHeaders()
    {
        fwrite($this->SHPFile, pack('NNNNNN', self::MAGIC, 0, 0, 0, 0, 0));
        fwrite($this->SHPFile, pack('N', $this->fileLength));
        fwrite($this->SHPFile, pack('V', 1000));
        fwrite($this->SHPFile, pack('V', $this->shapeType));
        $this->_saveBBox($this->SHPFile);

        fwrite($this->SHXFile, pack('NNNNNN', self::MAGIC, 0, 0, 0, 0, 0));
        fwrite($this->SHXFile, pack('N', 50 + 4 * count($this->records)));
        fwrite($this->SHXFile, pack('V', 1000));
        fwrite($this->SHXFile, pack('V', $this->shapeType));
        $this->_saveBBox($this->SHXFile);
    }
647603
function _storeExternsheetBiff8()
    {
        $total_references = count($this->_parser->_references);
        $record   = 0x0017;                     // Record identifier
        $length   = 2 + 6 * $total_references;  // Number of bytes to follow

        $supbook_index = 0;           // FIXME: only using internal SUPBOOK record
        $header           = pack("vv",  $record, $length);
        $data             = pack('v', $total_references);
        for ($i = 0; $i < $total_references; $i++) {
            $data .= $this->_parser->_references[$i];
        }
        $this->_append($header . $data);
    }
479268
public function footer()
    {
        if ($this->failures) {
            $this->output->write($this->getCountString($this->failures, true));
            $this->output->write(',');
        }

        $this->output->write($this->getCountString($this->successes, false));
        $this->output->writeln(sprintf(' (%d total)', $this->failures + $this->successes));
    }
257093
public function renderTableFooter()
	{
		$hasFilter = $this->filter !== null && $this->filterPosition === self::FILTER_POS_FOOTER;

		$hasFooter = $this->getHasFooter();
		if ($this->bulk !== null || $hasFilter || $hasFooter) {
			echo "<tfoot>\n";
			if ($hasFooter) {
				echo "<tr>\n";
				/** @var $column CDataColumn */
				foreach ($this->columns as $column) {
					$column->renderFooterCell();
				}
				echo "</tr>\n";
			}
			if ($hasFilter) {
				$this->renderFilter();
			}

			if ($this->bulk !== null) {
				$this->renderBulkActions();
			}
			echo "</tfoot>\n";
		}
	}