diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php index 99927c68..4bbe5ddf 100644 --- a/src/PhpWord/Element/AbstractContainer.php +++ b/src/PhpWord/Element/AbstractContainer.php @@ -23,6 +23,23 @@ use PhpOffice\PhpWord\PhpWord; /** * Container abstract class * + * @method Text addText($text, $fStyle = null, $pStyle = null) + * @method TextRun addTextRun($pStyle = null) + * @method Link addLink($target, $text = null, $fStyle = null, $pStyle = null) + * @method PreserveText addPreserveText($text, $fStyle = null, $pStyle = null) + * @method void addTextBreak($count = 1, $fStyle = null, $pStyle = null) + * @method ListItem addListItem($text, $depth = 0, $fStyle = null, $listStyle = null, $pStyle = null) + * @method ListItemRun addListItemRun($depth = 0, $listStyle = null, $pStyle = null) + * @method Table addTable($style = null) + * @method Image addImage($source, $style = null, $isWatermark = false) + * @method Object addObject($source, $style = null) + * @method Footnote addFootnote($pStyle = null) + * @method Endnote addEndnote($pStyle = null) + * @method CheckBox addCheckBox($name, $text, $fStyle = null, $pStyle = null) + * @method TextBox addTextBox($style = null) + * @method Field addField($type = null, $properties = array(), $options = array()) + * @method Line addLine($lineStyle = null) + * * @since 0.10.0 */ abstract class AbstractContainer extends AbstractElement @@ -41,6 +58,53 @@ abstract class AbstractContainer extends AbstractElement */ protected $container; + /** + * Magic method to catch all 'addElement' variation + * + * This removes addText, addTextRun, etc. When adding new element, we have to + * add the model in the class docblock with `@method`. + * + * Warning: This makes capitalization matters, e.g. addCheckbox or addcheckbox won't work. + * + * @param mixed $function + * @param mixed $args + * @return \PhpOffice\PhpWord\Element\AbstractElement + */ + public function __call($function, $args) + { + $elements = array('Text', 'TextRun', 'Link', 'PreserveText', 'TextBreak', + 'ListItem', 'ListItemRun', 'Table', 'Image', 'Object', 'Footnote', + 'Endnote', 'CheckBox', 'TextBox', 'Field', 'Line'); + $functions = array(); + for ($i = 0; $i < count($elements); $i++) { + $functions[$i] = 'add' . $elements[$i]; + } + + // Run valid `add` command + if (in_array($function, $functions)) { + $element = str_replace('add', '', $function); + + // Special case for TextBreak + // @todo Remove the `$count` parameter in 1.0.0 to make this element similiar to other elements? + if ($element == 'TextBreak') { + @list($count, $fontStyle, $paragraphStyle) = $args; // Suppress error + if ($count === null) { + $count = 1; + } + for ($i = 1; $i <= $count; $i++) { + $this->addElement($element, $fontStyle, $paragraphStyle); + } + + // All other elements + } else { + array_unshift($args, $element); // Prepend element name to the beginning of args array + return call_user_func_array(array($this, 'addElement'), $args); + } + } + + return null; + } + /** * Add element * @@ -156,209 +220,6 @@ abstract class AbstractContainer extends AbstractElement } } - /** - * Add text/preservetext element - * - * @param string $text - * @param mixed $fontStyle - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\Text|\PhpOffice\PhpWord\Element\PreserveText - */ - public function addText($text, $fontStyle = null, $paragraphStyle = null) - { - return $this->addElement('Text', $text, $fontStyle, $paragraphStyle); - } - - /** - * Add textrun element - * - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\TextRun - */ - public function addTextRun($paragraphStyle = null) - { - return $this->addElement('TextRun', $paragraphStyle); - } - - /** - * Add link element - * - * @param string $target - * @param string $text - * @param mixed $fontStyle - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\Link - */ - public function addLink($target, $text = null, $fontStyle = null, $paragraphStyle = null) - { - return $this->addElement('Link', $target, $text, $fontStyle, $paragraphStyle); - } - - /** - * Add preserve text element - * - * @param string $text - * @param mixed $fontStyle - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\PreserveText - */ - public function addPreserveText($text, $fontStyle = null, $paragraphStyle = null) - { - return $this->addElement('PreserveText', $text, $fontStyle, $paragraphStyle); - } - - /** - * Add text break element - * - * @param int $count - * @param mixed $fontStyle - * @param mixed $paragraphStyle - */ - public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null) - { - for ($i = 1; $i <= $count; $i++) { - $this->addElement('TextBreak', $fontStyle, $paragraphStyle); - } - } - - /** - * Add listitem element - * - * @param string $text - * @param int $depth - * @param mixed $fontStyle - * @param mixed $listStyle - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\ListItem - */ - public function addListItem($text, $depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null) - { - return $this->addElement('ListItem', $text, $depth, $fontStyle, $listStyle, $paragraphStyle); - } - - /** - * Add listitemrun element - * - * @param int $depth - * @param mixed $listStyle - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\ListItemRun - */ - public function addListItemRun($depth = 0, $listStyle = null, $paragraphStyle = null) - { - return $this->addElement('ListItemRun', $depth, $listStyle, $paragraphStyle); - } - - /** - * Add table element - * - * @param mixed $style - * @return \PhpOffice\PhpWord\Element\Table - */ - public function addTable($style = null) - { - return $this->addElement('Table', $style); - } - - /** - * Add image element - * - * @param string $source - * @param mixed $style Image style - * @param bool $isWatermark - * @return \PhpOffice\PhpWord\Element\Image - */ - public function addImage($source, $style = null, $isWatermark = false) - { - return $this->addElement('Image', $source, $style, $isWatermark); - } - - /** - * Add OLE-object element - * - * All exceptions should be handled by \PhpOffice\PhpWord\Element\Object - * - * @param string $source - * @param mixed $style - * @return \PhpOffice\PhpWord\Element\Object - */ - public function addObject($source, $style = null) - { - return $this->addElement('Object', $source, $style); - } - - /** - * Add footnote element - * - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\Footnote - */ - public function addFootnote($paragraphStyle = null) - { - return $this->addElement('Footnote', $paragraphStyle); - } - - /** - * Add endnote element - * - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\Endnote - */ - public function addEndnote($paragraphStyle = null) - { - return $this->addElement('Endnote', $paragraphStyle); - } - - /** - * Add a CheckBox Element - * - * @param string $name - * @param string $text - * @param mixed $fontStyle - * @param mixed $paragraphStyle - * @return \PhpOffice\PhpWord\Element\CheckBox - */ - public function addCheckBox($name, $text, $fontStyle = null, $paragraphStyle = null) - { - return $this->addElement('CheckBox', $name, $text, $fontStyle, $paragraphStyle); - } - - /** - * Add textbox element - * - * @param mixed $style - * @return \PhpOffice\PhpWord\Element\TextBox - */ - public function addTextBox($style = null) - { - return $this->addElement('TextBox', $style); - } - - /** - * Add field element - * - * @param string $type - * @param array $properties - * @param array $options - * @return \PhpOffice\PhpWord\Element\Field - */ - public function addField($type = null, $properties = array(), $options = array()) - { - return $this->addElement('Field', $type, $properties, $options); - } - - /** - * Add line element - * - * @param mixed $lineStyle - * @return \PhpOffice\PhpWord\Element\Line - */ - public function addLine($lineStyle = null) - { - return $this->addElement('Line', $lineStyle); - - } - /** * Check if a method is allowed for the current container * diff --git a/src/PhpWord/IOFactory.php b/src/PhpWord/IOFactory.php index 1d784962..166ea152 100644 --- a/src/PhpWord/IOFactory.php +++ b/src/PhpWord/IOFactory.php @@ -20,7 +20,7 @@ namespace PhpOffice\PhpWord; use PhpOffice\PhpWord\Exception\Exception; /** - * IO factory + * IO Factory */ abstract class IOFactory { @@ -34,12 +34,12 @@ abstract class IOFactory */ public static function createWriter(PhpWord $phpWord, $name = 'Word2007') { - if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML', 'PDF'))) { + $class = 'PhpOffice\\PhpWord\\Writer\\' . $name; + if (class_exists($class) && self::isConcreteClass($class)) { + return new $class($phpWord); + } else { throw new Exception("\"{$name}\" is not a valid writer."); } - - $fqName = "PhpOffice\\PhpWord\\Writer\\{$name}"; - return new $fqName($phpWord); } /** @@ -51,12 +51,12 @@ abstract class IOFactory */ public static function createReader($name = 'Word2007') { - if (!in_array($name, array('ReaderInterface', 'Word2007', 'ODText', 'RTF', 'HTML'))) { + $class = 'PhpOffice\\PhpWord\\Reader\\' . $name; + if (class_exists($class) && self::isConcreteClass($class)) { + return new $class(); + } else { throw new Exception("\"{$name}\" is not a valid reader."); } - - $fqName = "PhpOffice\\PhpWord\\Reader\\{$name}"; - return new $fqName(); } /** @@ -69,6 +69,20 @@ abstract class IOFactory public static function load($filename, $readerName = 'Word2007') { $reader = self::createReader($readerName); + return $reader->load($filename); } + + /** + * Check if it's a concrete class (not abstract nor interface) + * + * @param string $class + * @return bool + */ + private static function isConcreteClass($class) + { + $reflection = new \ReflectionClass($class); + + return !$reflection->isAbstract() && !$reflection->isInterface(); + } } diff --git a/tests/PhpWord/Tests/Writer/Word2007/Part/DocumentTest.php b/tests/PhpWord/Tests/Writer/Word2007/Part/DocumentTest.php index 7ff4cb7c..e27d072a 100644 --- a/tests/PhpWord/Tests/Writer/Word2007/Part/DocumentTest.php +++ b/tests/PhpWord/Tests/Writer/Word2007/Part/DocumentTest.php @@ -355,10 +355,10 @@ class DocumentTest extends \PHPUnit_Framework_TestCase $pStyle = 'pStyle'; $phpWord = new PhpWord(); - $phpWord->addFontStyle($rStyle, array('bold' => true)); - $phpWord->addParagraphStyle($pStyle, array('hanging' => 120, 'indent' => 120)); + // $phpWord->addFontStyle($rStyle, array('bold' => true)); + // $phpWord->addParagraphStyle($pStyle, array('hanging' => 120, 'indent' => 120)); $section = $phpWord->addSection(); - $section->addCheckbox('Check1', 'Test', $rStyle, $pStyle); + $section->addCheckBox('Check1', 'Test', $rStyle, $pStyle); $doc = TestHelperDOCX::getDocument($phpWord); $element = '/w:document/w:body/w:p/w:r/w:fldChar/w:ffData/w:name';