Completed
Push — develop ( dfd31d...f6e11d )
by
unknown
17:02
created

Module::setServiceManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
/**
3
 * YAWIK
4
 * Auth Module Bootstrap
5
 *
6
 * @copyright (c) 2013 - 2016 Cross Solution (http://cross-solution.de)
7
 * @license   MIT
8
 */
9
10
namespace Pdf;
11
12
use Zend\ServiceManager\ServiceManager;
13
use SplFileInfo;
14
use Zend\View\Resolver\ResolverInterface;
15
use Zend\View\Renderer\RendererInterface as Renderer;
16
use Zend\Mvc\MvcEvent;
17
use Zend\View\ViewEvent;
18
use Zend\EventManager\EventManagerInterface;
19
use Core\Html2Pdf\PdfInterface;
20
use Core\View\Helper\InsertFile\FileEvent;
21
use Core\Entity\FileEntity;
22
use Core\ModuleManager\ModuleConfigLoader;
23
24
/**
25
 * Make HTML to PDF
26
 *
27
 */
28
class Module implements PdfInterface, ResolverInterface
29
{
30
    const RENDER_FULL = 0;
31
    const RENDER_WITHOUT_PDF = 1;
32
    const RENDER_WITHOUT_ATTACHMENTS = 2;
33
    
34
    protected $serviceManager;
35
    
36
    protected $viewResolverAttached = false;
37
    
38
    protected $appendPDF = array();
39
    protected $appendImage = array();
40
    
41
    
42
     /**
43
     * Loads module specific configuration.
44
     *
45
     * @return array
46
     */
47
    public function getConfig()
48
    {
49
        return ModuleConfigLoader::load(__DIR__ . '/config');
50
    }
51
    
52
    public static function factory(ServiceManager $serviceManager)
53
    {
54
        $module = new static();
55
        $module->serviceManager = $serviceManager;
56
        return $module;
57
    }
58
    
59
    public function onBootstrap(MvcEvent $e)
60
    {
61
        $eventManager = $e->getApplication()->getEventManager();
62
        $eventManager->getSharedManager()->attach(
63
            'Applications',
64
            'application.detail.actionbuttons',
65
            function ($event) {
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
66
                return 'pdf/application/details/button';
67
            }
68
        );
69
    }
70
    
71
    /**
72
     * hook into the rendering for transformation of HTML to PDF
73
     * @param \Zend\EventManager\EventManagerInterface $events
74
     */
75
    public function attach(EventManagerInterface $events)
76
    {
77
        $events->attach(ViewEvent::EVENT_RENDERER_POST, array($this, 'cleanLayout'), 1);
78
        $events->attach(ViewEvent::EVENT_RESPONSE, array($this, 'attachPDFtransformer'), 10);
79
    }
80
    
81
    /**
82
     * hook into the MVC
83
     * in here you could still decide, if you want to hook into the Rendering
84
     * @param \Zend\EventManager\EventManagerInterface $events
85
     */
86
    public function attachMvc(EventManagerInterface $events)
87
    {
88
        $events->attach(MvcEvent::EVENT_RENDER, array($this, 'initializeViewHelper'), 100);
89
    }
90
    
91
    /**
92
     * hook into the Rendering of files
93
     * the manager to hook in is the viewhelper 'insertfiles'
94
     *
95
     * @param \Zend\Mvc\MvcEvent $e
96
     */
97
    public function initializeViewHelper(MvcEvent $e)
0 ignored issues
show
Unused Code introduced by
The parameter $e is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
98
    {
99
        $viewhelperManager = $this->serviceManager->get('ViewhelperManager');
100
        if ($viewhelperManager->has('insertFile')) {
101
            $insertFile = $viewhelperManager->get('insertFile');
102
            $insertFile->attach(FileEvent::GETFILE, array($this, 'getFile'));
103
            $insertFile->attach(FileEvent::RENDERFILE, array($this, 'renderFile'));
104
            $insertFile->attach(FileEvent::INSERTFILE, array($this, 'collectFiles'));
105
        }
106
    }
107
    
108
    /**
109
     * proxy, in case that you just got a name and have to find the associated file-entity
110
     * maybe this is redundant and can be deprecated
111
     *
112
     * @param \Core\View\Helper\InsertFile\FileEvent $e
113
     * @return null
114
     */
115
    public function getFile(FileEvent $e)
116
    {
117
        $lastFileName = $e->getLastFileName();
118
        if (is_string($lastFileName)) {
119
            $repository = $this->serviceManager->get('repositories')->get('Applications/Attachment');
120
            $file       = $repository->find($lastFileName);
121
            if (isset($file)) {
122
                $e->setFileObject($lastFileName, $file);
123
                $e->stopPropagation();
124
                return $file;
125
            }
126
            return null;
127
        }
128
        // if it is not a string i do presume it is already a file-Object
129
        return $lastFileName;
130
    }
131
    
132
    /**
133
     * here the inserted File is rendered,
134
     * there is a lot which still can be done like outsorcing the HTML to a template,
135
     * or distinguish between different File Types,
136
     * at the moment we assume the $file is always an (sub-)instance of \Core\File\Entity
137
     *
138
     * @param \Core\View\Helper\InsertFile\FileEvent $e
139
     * @return string
140
     */
141
    public function renderFile(FileEvent $e)
142
    {
143
        $file = $e->getLastFileObject();
144
        // assume it is of the class Core\Entity\FileEntity
145
        $return = '<div class="col-md-3"><a href="#attachment_' . $file->getId() . '">' . $file->getName() . '</a></div>' . PHP_EOL
146
                . '<div class="col-md-3">' . $file->getType() . '</div>'
147
                . '<div class="col-md-3">' . $file->prettySize . '</div>';
148
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
41% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
149
         * this snippet was for direct inserting an image into the PDF
150
        if ($file && $file instanceOf FileEntity && 0 === strpos($file->getType(), 'image')) {
151
            //$content = $file->getContent();
152
            //$url = 'data:image/' . $file->getType() . ';base64,' . base64_encode ($content);
153
            //$html = '<img src="' . $url . '" >';
154
            $html = '<a href="#1">' . $file->getName() . '</a>';
155
            $e->stopPropagation();
156
            return $html;
157
        }
158
         */
159
        return $return;
160
    }
161
162
    /**
163
     * give a summary of all inserted Files,
164
     * this is for having access to those files in the post-process
165
     * @param \Core\View\Helper\InsertFile\FileEvent|\Zend\View\ViewEvent $e
166
     * @return NULL
167
     */
168
    public function collectFiles(FileEvent $e)
169
    {
170
        $this->appendPDF = array();
171
        $files = $e->getAllFiles();
172
        foreach ($files as $name => $file) {
173
            if (!empty($file) && $file instanceof FileEntity) {
174
                if (0 === strpos($file->getType(), 'image')) {
175
                    $this->appendImage[] = $file;
176
                }
177
                if (strtolower($file->getType()) == 'application/pdf') {
178
                    $this->appendPDF[] = $file;
179
                }
180
            }
181
        }
182
        return null;
183
    }
184
    
185
    /**
186
     * remove unwanted or layout related data
187
     *
188
     * basically you rake through the viewmodel for the data you want to use for your template,
189
     * this may not be optimal because you have to rely on the correct naming of the viewmodels
190
     *
191
     * if you get the data you want, you switch to the specific template by adding the conforming resolver
192
     *
193
     * @param \Zend\View\ViewEvent $e
194
     */
195
    public function cleanLayout(ViewEvent $e)
196
    {
197
        $result   = $e->getResult();
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
198
        $response = $e->getResponse();
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
199
        $model = $e->getModel();
200
        if ($model->hasChildren()) {
201
            $children = $model->getChildren();
202
            $content = null;
203
            foreach ($children as $child) {
204
                if ($child->captureTo() == 'content') {
205
                    $content = $child;
206
                    $this->attachViewResolver();
207
                }
208
            }
209
            if (!empty($content)) {
210
                $e->setModel($content);
211
            }
212
        } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
213
            // attach the own resolver here too ?
214
            // ...
215
        }
216
    }
217
    
218
    /**
219
     * Attach an own ViewResolver
220
     */
221
    public function attachViewResolver()
222
    {
223
        if (!$this->viewResolverAttached) {
224
            $this->viewResolverAttached = true;
225
            $resolver = $this->serviceManager->get('ViewResolver');
226
            $resolver->attach($this, 100);
227
        }
228
    }
229
    
230
    /**
231
     * Transform the HTML to PDF,
232
     * this is a post-rendering-process
233
     *
234
     * put in here everything related to the transforming-process like options
235
     *
236
     * @param \Zend\View\ViewEvent $e
237
     */
238
    public function attachPDFtransformer(ViewEvent $e)
239
    {
240
        
241
        //$renderer = $e->getRenderer();
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
242
        $result   = $e->getResult();
0 ignored issues
show
Bug introduced by
The method getResult does only exist in Zend\View\ViewEvent, but not in Exception.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
243
        $response = $e->getResponse();
0 ignored issues
show
Bug introduced by
The method getResponse does only exist in Zend\View\ViewEvent, but not in Exception.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
244
        
245
        // the handles are for temporary files
246
        error_reporting(0);
247
        foreach (array(self::RENDER_FULL, self::RENDER_WITHOUT_PDF, self::RENDER_WITHOUT_ATTACHMENTS ) as $render) {
248
            $handles = array();
249
            try {
250
                $pdf = new extern\mPDFderive();
251
                $pdf->SetImportUse();
252
                // create bookmark list in Acrobat Reader
253
                $pdf->h2bookmarks = array('H1' => 0, 'H2' => 1, 'H3' => 2);
254
                $pdf->WriteHTML($result);
255
256
                // Output of the Images
257
                if (self::RENDER_FULL == $render || self::RENDER_WITHOUT_PDF == $render) {
258
                    if (is_array($this->appendImage) && !empty($this->appendImage)) {
259
                        foreach ($this->appendImage as $imageAttachment) {
260
                            $content = $imageAttachment->getContent();
261
                            $url = 'data:image/' . $imageAttachment->getType() . ';base64,' . base64_encode($content);
262
                            $html = '<a name="attachment_' . $imageAttachment->getId() . '"><img src="' . $url . '" /><br /></a>';
263
                            $pdf->WriteHTML($html);
264
                        }
265
                    }
266
                }
267
268
                // Temp Files PDF
269
                if (self::RENDER_FULL == $render) {
270
                    if (is_array($this->appendPDF) && !empty($this->appendPDF)) {
271
                        foreach ($this->appendPDF as $pdfAttachment) {
272
                            $content = $pdfAttachment->getContent();
273
                            $tmpHandle = tmpfile();
274
                            $handles[] = $tmpHandle;
275
                            fwrite($tmpHandle, $content);
276
                            fseek($tmpHandle, 0);
277
                        }
278
                    }
279
                }
280
281
                // Output of the PDF
282
                foreach ($handles as $handle) {
283
                    $meta_data = stream_get_meta_data($handle);
0 ignored issues
show
Coding Style introduced by
$meta_data does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
284
                    $filename = $meta_data["uri"];
0 ignored issues
show
Coding Style introduced by
$meta_data does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
285
                    $pdf->WriteHTML($filename);
286
                    $pagecount = $pdf->SetSourceFile($filename);
287
                    for ($pages = 0; $pages < $pagecount; $pages++) {
288
                        $pdf->AddPage();
289
                        $pdf->WriteHTML(' pages: ' . $pagecount);
290
                        $tx = $pdf->ImportPage($pages + 1);
291
                        $pdf->UseTemplate($tx);
292
                    }
293
                }
294
295
                $pdf_result = $pdf->Output();
0 ignored issues
show
Coding Style introduced by
$pdf_result does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
296
                $e->setResult($pdf_result);
0 ignored issues
show
Coding Style introduced by
$pdf_result does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Bug introduced by
The method setResult does only exist in Zend\View\ViewEvent, but not in Exception.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
297
298
                // delete all temporary Files again
299
                foreach ($handles as $handle) {
300
                    fclose($handle);
301
                }
302
                break;
303
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
304
            }
305
        }
306
        error_reporting(E_ALL);
307
    }
308
    
309
    /**
310
     * Look for a template with the Suffix ".pdf.phtml"
311
     *
312
     * @param string $name
313
     * @param \Zend\View\Renderer\RendererInterface $renderer
0 ignored issues
show
Documentation introduced by
Should the type for parameter $renderer not be null|Renderer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
314
     * @return string|boolean
315
     */
316
    public function resolve($name, Renderer $renderer = null)
317
    {
318
        if ($this->serviceManager->has('ViewTemplatePathStack')) {
319
            // get all the Pases made up for the zend-provided resolver
320
            // we won't get any closer to ALL than that
321
            $viewTemplatePathStack = $this->serviceManager->get('ViewTemplatePathStack');
322
            $paths = $viewTemplatePathStack->getPaths();
323
            $defaultSuffix = $viewTemplatePathStack->getDefaultSuffix();
324
            if (pathinfo($name, PATHINFO_EXTENSION) != $defaultSuffix) {
325
                ;
326
                $name .= '.pdf.' . $defaultSuffix;
327
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
328
                // TODO: replace Filename by Filename for PDF
329
            }
330
331
            foreach ($paths as $path) {
332
                $file = new SplFileInfo($path . $name);
333
                if ($file->isReadable()) {
334
                    // Found! Return it.
335
                    if (($filePath = $file->getRealPath()) === false && substr($path, 0, 7) === 'phar://') {
336
                        // Do not try to expand phar paths (realpath + phars == fail)
337
                        $filePath = $path . $name;
338
                        if (!file_exists($filePath)) {
339
                            break;
340
                        }
341
                    }
342
                    //if ($this->useStreamWrapper()) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
343
                    //    // If using a stream wrapper, prepend the spec to the path
344
                    //    $filePath = 'zend.view://' . $filePath;
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
345
                    //}
346
                    return $filePath;
347
                }
348
            }
349
        }
350
        // TODO: Resolving to an PDF has failed, this could have implications for the transformer
351
        return false;
352
    }
353
}
354