Skip to content

Commit e0d2c65

Browse files
committed
Refactor IOFactory and AbstractContainer to allow more dynamic inclusion.
1 parent 9839222 commit e0d2c65

File tree

3 files changed

+90
-215
lines changed

3 files changed

+90
-215
lines changed

src/PhpWord/Element/AbstractContainer.php

Lines changed: 64 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@
2323
/**
2424
* Container abstract class
2525
*
26+
* @method Text addText($text, $fStyle = null, $pStyle = null)
27+
* @method TextRun addTextRun($pStyle = null)
28+
* @method Link addLink($target, $text = null, $fStyle = null, $pStyle = null)
29+
* @method PreserveText addPreserveText($text, $fStyle = null, $pStyle = null)
30+
* @method void addTextBreak($count = 1, $fStyle = null, $pStyle = null)
31+
* @method ListItem addListItem($text, $depth = 0, $fStyle = null, $listStyle = null, $pStyle = null)
32+
* @method ListItemRun addListItemRun($depth = 0, $listStyle = null, $pStyle = null)
33+
* @method Table addTable($style = null)
34+
* @method Image addImage($source, $style = null, $isWatermark = false)
35+
* @method Object addObject($source, $style = null)
36+
* @method Footnote addFootnote($pStyle = null)
37+
* @method Endnote addEndnote($pStyle = null)
38+
* @method CheckBox addCheckBox($name, $text, $fStyle = null, $pStyle = null)
39+
* @method TextBox addTextBox($style = null)
40+
* @method Field addField($type = null, $properties = array(), $options = array())
41+
* @method Line addLine($lineStyle = null)
42+
*
2643
* @since 0.10.0
2744
*/
2845
abstract class AbstractContainer extends AbstractElement
@@ -41,6 +58,53 @@ abstract class AbstractContainer extends AbstractElement
4158
*/
4259
protected $container;
4360

61+
/**
62+
* Magic method to catch all 'addElement' variation
63+
*
64+
* This removes addText, addTextRun, etc. When adding new element, we have to
65+
* add the model in the class docblock with `@method`.
66+
*
67+
* Warning: This makes capitalization matters, e.g. addCheckbox or addcheckbox won't work.
68+
*
69+
* @param mixed $function
70+
* @param mixed $args
71+
* @return \PhpOffice\PhpWord\Element\AbstractElement
72+
*/
73+
public function __call($function, $args)
74+
{
75+
$elements = array('Text', 'TextRun', 'Link', 'PreserveText', 'TextBreak',
76+
'ListItem', 'ListItemRun', 'Table', 'Image', 'Object', 'Footnote',
77+
'Endnote', 'CheckBox', 'TextBox', 'Field', 'Line');
78+
$functions = array();
79+
for ($i = 0; $i < count($elements); $i++) {
80+
$functions[$i] = 'add' . $elements[$i];
81+
}
82+
83+
// Run valid `add` command
84+
if (in_array($function, $functions)) {
85+
$element = str_replace('add', '', $function);
86+
87+
// Special case for TextBreak
88+
// @todo Remove the `$count` parameter in 1.0.0 to make this element similiar to other elements?
89+
if ($element == 'TextBreak') {
90+
@list($count, $fontStyle, $paragraphStyle) = $args; // Suppress error
91+
if ($count === null) {
92+
$count = 1;
93+
}
94+
for ($i = 1; $i <= $count; $i++) {
95+
$this->addElement($element, $fontStyle, $paragraphStyle);
96+
}
97+
98+
// All other elements
99+
} else {
100+
array_unshift($args, $element); // Prepend element name to the beginning of args array
101+
return call_user_func_array(array($this, 'addElement'), $args);
102+
}
103+
}
104+
105+
return null;
106+
}
107+
44108
/**
45109
* Add element
46110
*
@@ -156,209 +220,6 @@ private function setElementRelationId(AbstractElement $element, $elementName, $s
156220
}
157221
}
158222

159-
/**
160-
* Add text/preservetext element
161-
*
162-
* @param string $text
163-
* @param mixed $fontStyle
164-
* @param mixed $paragraphStyle
165-
* @return \PhpOffice\PhpWord\Element\Text|\PhpOffice\PhpWord\Element\PreserveText
166-
*/
167-
public function addText($text, $fontStyle = null, $paragraphStyle = null)
168-
{
169-
return $this->addElement('Text', $text, $fontStyle, $paragraphStyle);
170-
}
171-
172-
/**
173-
* Add textrun element
174-
*
175-
* @param mixed $paragraphStyle
176-
* @return \PhpOffice\PhpWord\Element\TextRun
177-
*/
178-
public function addTextRun($paragraphStyle = null)
179-
{
180-
return $this->addElement('TextRun', $paragraphStyle);
181-
}
182-
183-
/**
184-
* Add link element
185-
*
186-
* @param string $target
187-
* @param string $text
188-
* @param mixed $fontStyle
189-
* @param mixed $paragraphStyle
190-
* @return \PhpOffice\PhpWord\Element\Link
191-
*/
192-
public function addLink($target, $text = null, $fontStyle = null, $paragraphStyle = null)
193-
{
194-
return $this->addElement('Link', $target, $text, $fontStyle, $paragraphStyle);
195-
}
196-
197-
/**
198-
* Add preserve text element
199-
*
200-
* @param string $text
201-
* @param mixed $fontStyle
202-
* @param mixed $paragraphStyle
203-
* @return \PhpOffice\PhpWord\Element\PreserveText
204-
*/
205-
public function addPreserveText($text, $fontStyle = null, $paragraphStyle = null)
206-
{
207-
return $this->addElement('PreserveText', $text, $fontStyle, $paragraphStyle);
208-
}
209-
210-
/**
211-
* Add text break element
212-
*
213-
* @param int $count
214-
* @param mixed $fontStyle
215-
* @param mixed $paragraphStyle
216-
*/
217-
public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null)
218-
{
219-
for ($i = 1; $i <= $count; $i++) {
220-
$this->addElement('TextBreak', $fontStyle, $paragraphStyle);
221-
}
222-
}
223-
224-
/**
225-
* Add listitem element
226-
*
227-
* @param string $text
228-
* @param int $depth
229-
* @param mixed $fontStyle
230-
* @param mixed $listStyle
231-
* @param mixed $paragraphStyle
232-
* @return \PhpOffice\PhpWord\Element\ListItem
233-
*/
234-
public function addListItem($text, $depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null)
235-
{
236-
return $this->addElement('ListItem', $text, $depth, $fontStyle, $listStyle, $paragraphStyle);
237-
}
238-
239-
/**
240-
* Add listitemrun element
241-
*
242-
* @param int $depth
243-
* @param mixed $listStyle
244-
* @param mixed $paragraphStyle
245-
* @return \PhpOffice\PhpWord\Element\ListItemRun
246-
*/
247-
public function addListItemRun($depth = 0, $listStyle = null, $paragraphStyle = null)
248-
{
249-
return $this->addElement('ListItemRun', $depth, $listStyle, $paragraphStyle);
250-
}
251-
252-
/**
253-
* Add table element
254-
*
255-
* @param mixed $style
256-
* @return \PhpOffice\PhpWord\Element\Table
257-
*/
258-
public function addTable($style = null)
259-
{
260-
return $this->addElement('Table', $style);
261-
}
262-
263-
/**
264-
* Add image element
265-
*
266-
* @param string $source
267-
* @param mixed $style Image style
268-
* @param bool $isWatermark
269-
* @return \PhpOffice\PhpWord\Element\Image
270-
*/
271-
public function addImage($source, $style = null, $isWatermark = false)
272-
{
273-
return $this->addElement('Image', $source, $style, $isWatermark);
274-
}
275-
276-
/**
277-
* Add OLE-object element
278-
*
279-
* All exceptions should be handled by \PhpOffice\PhpWord\Element\Object
280-
*
281-
* @param string $source
282-
* @param mixed $style
283-
* @return \PhpOffice\PhpWord\Element\Object
284-
*/
285-
public function addObject($source, $style = null)
286-
{
287-
return $this->addElement('Object', $source, $style);
288-
}
289-
290-
/**
291-
* Add footnote element
292-
*
293-
* @param mixed $paragraphStyle
294-
* @return \PhpOffice\PhpWord\Element\Footnote
295-
*/
296-
public function addFootnote($paragraphStyle = null)
297-
{
298-
return $this->addElement('Footnote', $paragraphStyle);
299-
}
300-
301-
/**
302-
* Add endnote element
303-
*
304-
* @param mixed $paragraphStyle
305-
* @return \PhpOffice\PhpWord\Element\Endnote
306-
*/
307-
public function addEndnote($paragraphStyle = null)
308-
{
309-
return $this->addElement('Endnote', $paragraphStyle);
310-
}
311-
312-
/**
313-
* Add a CheckBox Element
314-
*
315-
* @param string $name
316-
* @param string $text
317-
* @param mixed $fontStyle
318-
* @param mixed $paragraphStyle
319-
* @return \PhpOffice\PhpWord\Element\CheckBox
320-
*/
321-
public function addCheckBox($name, $text, $fontStyle = null, $paragraphStyle = null)
322-
{
323-
return $this->addElement('CheckBox', $name, $text, $fontStyle, $paragraphStyle);
324-
}
325-
326-
/**
327-
* Add textbox element
328-
*
329-
* @param mixed $style
330-
* @return \PhpOffice\PhpWord\Element\TextBox
331-
*/
332-
public function addTextBox($style = null)
333-
{
334-
return $this->addElement('TextBox', $style);
335-
}
336-
337-
/**
338-
* Add field element
339-
*
340-
* @param string $type
341-
* @param array $properties
342-
* @param array $options
343-
* @return \PhpOffice\PhpWord\Element\Field
344-
*/
345-
public function addField($type = null, $properties = array(), $options = array())
346-
{
347-
return $this->addElement('Field', $type, $properties, $options);
348-
}
349-
350-
/**
351-
* Add line element
352-
*
353-
* @param mixed $lineStyle
354-
* @return \PhpOffice\PhpWord\Element\Line
355-
*/
356-
public function addLine($lineStyle = null)
357-
{
358-
return $this->addElement('Line', $lineStyle);
359-
360-
}
361-
362223
/**
363224
* Check if a method is allowed for the current container
364225
*

src/PhpWord/IOFactory.php

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use PhpOffice\PhpWord\Exception\Exception;
2121

2222
/**
23-
* IO factory
23+
* IO Factory
2424
*/
2525
abstract class IOFactory
2626
{
@@ -34,12 +34,12 @@ abstract class IOFactory
3434
*/
3535
public static function createWriter(PhpWord $phpWord, $name = 'Word2007')
3636
{
37-
if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML', 'PDF'))) {
37+
$class = 'PhpOffice\\PhpWord\\Writer\\' . $name;
38+
if (class_exists($class) && self::isConcreteClass($class)) {
39+
return new $class($phpWord);
40+
} else {
3841
throw new Exception("\"{$name}\" is not a valid writer.");
3942
}
40-
41-
$fqName = "PhpOffice\\PhpWord\\Writer\\{$name}";
42-
return new $fqName($phpWord);
4343
}
4444

4545
/**
@@ -51,12 +51,12 @@ public static function createWriter(PhpWord $phpWord, $name = 'Word2007')
5151
*/
5252
public static function createReader($name = 'Word2007')
5353
{
54-
if (!in_array($name, array('ReaderInterface', 'Word2007', 'ODText', 'RTF', 'HTML'))) {
54+
$class = 'PhpOffice\\PhpWord\\Reader\\' . $name;
55+
if (class_exists($class) && self::isConcreteClass($class)) {
56+
return new $class();
57+
} else {
5558
throw new Exception("\"{$name}\" is not a valid reader.");
5659
}
57-
58-
$fqName = "PhpOffice\\PhpWord\\Reader\\{$name}";
59-
return new $fqName();
6060
}
6161

6262
/**
@@ -69,6 +69,20 @@ public static function createReader($name = 'Word2007')
6969
public static function load($filename, $readerName = 'Word2007')
7070
{
7171
$reader = self::createReader($readerName);
72+
7273
return $reader->load($filename);
7374
}
75+
76+
/**
77+
* Check if it's a concrete class (not abstract nor interface)
78+
*
79+
* @param string $class
80+
* @return bool
81+
*/
82+
private static function isConcreteClass($class)
83+
{
84+
$reflection = new \ReflectionClass($class);
85+
86+
return !$reflection->isAbstract() && !$reflection->isInterface();
87+
}
7488
}

tests/PhpWord/Tests/Writer/Word2007/Part/DocumentTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,10 +355,10 @@ public function testWriteCheckbox()
355355
$pStyle = 'pStyle';
356356

357357
$phpWord = new PhpWord();
358-
$phpWord->addFontStyle($rStyle, array('bold' => true));
359-
$phpWord->addParagraphStyle($pStyle, array('hanging' => 120, 'indent' => 120));
358+
// $phpWord->addFontStyle($rStyle, array('bold' => true));
359+
// $phpWord->addParagraphStyle($pStyle, array('hanging' => 120, 'indent' => 120));
360360
$section = $phpWord->addSection();
361-
$section->addCheckbox('Check1', 'Test', $rStyle, $pStyle);
361+
$section->addCheckBox('Check1', 'Test', $rStyle, $pStyle);
362362
$doc = TestHelperDOCX::getDocument($phpWord);
363363

364364
$element = '/w:document/w:body/w:p/w:r/w:fldChar/w:ffData/w:name';

0 commit comments

Comments
 (0)