Completed
Push — develop ( 1aadc7...f2612d )
by
unknown
15:52 queued 05:10
created

Module::resolve()   C

Complexity

Conditions 8
Paths 13

Size

Total Lines 37
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 37
rs 5.3846
cc 8
eloc 17
nc 13
nop 2
1
<?php
2
/**
3
 * YAWIK
4
 * Auth Module Bootstrap
5
 *
6
 * @copyright (c) 2013-2015 Cross Solution (http://cross-solution.de)
7
 * @license   MIT
8
 */
9
10
namespace Pdf;
11
12
use Zend\ServiceManager\ServiceManagerAwareInterface;
13
use Zend\ServiceManager\ServiceManager;
14
use SplFileInfo;
15
use Zend\View\Resolver\ResolverInterface;
16
use Zend\View\Renderer\RendererInterface as Renderer;
17
use Zend\Mvc\MvcEvent;
18
use Zend\View\ViewEvent;
19
use Zend\View\Model\ViewModel;
20
use Zend\EventManager\EventManagerInterface;
21
use Core\Html2Pdf\PdfInterface;
22
//use Core\View\Helper\InsertFile;
23
use Core\View\Helper\InsertFile\FileEvent;
24
use Core\Entity\FileEntity;
25
use Core\ModuleManager\ModuleConfigLoader;
26
27
/**
28
 * Make HTML to PDF
29
 *
30
 */
31
class Module implements PdfInterface, ResolverInterface, ServiceManagerAwareInterface
32
{
33
    const RENDER_FULL = 0;
34
    const RENDER_WITHOUT_PDF = 1;
35
    const RENDER_WITHOUT_ATTACHMENTS = 2;
36
    
37
    protected $serviceManager;
38
    
39
    protected $viewResolverAttached = false;
40
    
41
    protected $appendPDF = array();
42
    protected $appendImage = array();
43
    
44
    
45
     /**
46
     * Loads module specific configuration.
47
     *
48
     * @return array
49
     */
50
    public function getConfig()
51
    {
52
        return ModuleConfigLoader::load(__DIR__ . '/config');
53
    }
54
    
55
    public function setServiceManager(ServiceManager $serviceManager)
56
    {
57
        $this->serviceManager = $serviceManager;
58
        return $this;
59
    }
60
    
61
    public function onBootstrap(MvcEvent $e)
62
    {
63
        $eventManager = $e->getApplication()->getEventManager();
64
        $eventManager->getSharedManager()->attach(
65
            'Applications',
66
            'application.detail.actionbuttons',
67
            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...
68
                return 'pdf/application/details/button';
69
            }
70
        );
71
    }
72
    
73
    /**
74
     * hook into the rendering for transformation of HTML to PDF
75
     * @param \Zend\EventManager\EventManagerInterface $events
76
     */
77
    public function attach(EventManagerInterface $events)
78
    {
79
        $events->attach(ViewEvent::EVENT_RENDERER_POST, array($this, 'cleanLayout'), 1);
80
        $events->attach(ViewEvent::EVENT_RESPONSE, array($this, 'attachPDFtransformer'), 10);
81
    }
82
    
83
    /**
84
     * hook into the MVC
85
     * in here you could still decide, if you want to hook into the Rendering
86
     * @param \Zend\EventManager\EventManagerInterface $events
87
     */
88
    public function attachMvc(EventManagerInterface $events)
89
    {
90
        $events->attach(MvcEvent::EVENT_RENDER, array($this, 'initializeViewHelper'), 100);
91
    }
92
    
93
    /**
94
     * hook into the Rendering of files
95
     * the manager to hook in is the viewhelper 'insertfiles'
96
     *
97
     * @param \Zend\Mvc\MvcEvent $e
98
     */
99
    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...
100
    {
101
        $viewhelperManager = $this->serviceManager->get('ViewhelperManager');
102
        if ($viewhelperManager->has('insertFile')) {
103
            $insertFile = $viewhelperManager->get('insertFile');
104
            $insertFile->attach(FileEvent::GETFILE, array($this, 'getFile'));
105
            $insertFile->attach(FileEvent::RENDERFILE, array($this, 'renderFile'));
106
            $insertFile->attach(FileEvent::INSERTFILE, array($this, 'collectFiles'));
107
        }
108
    }
109
    
110
    /**
111
     * proxy, in case that you just got a name and have to find the associated file-entity
112
     * maybe this is redundant and can be deprecated
113
     *
114
     * @param \Core\View\Helper\InsertFile\FileEvent $e
115
     * @return null
116
     */
117
    public function getFile(FileEvent $e)
118
    {
119
        $lastFileName = $e->getLastFileName();
120
        if (is_string($lastFileName)) {
121
            $repository = $this->serviceManager->get('repositories')->get('Applications/Attachment');
122
            $file       = $repository->find($lastFileName);
123
            if (isset($file)) {
124
                $e->setFileObject($lastFileName, $file);
125
                $e->stopPropagation();
126
                return $file;
127
            }
128
            return null;
129
        }
130
        // if it is not a string i do presume it is already a file-Object
131
        return $lastFileName;
132
    }
133
    
134
    /**
135
     * here the inserted File is rendered,
136
     * there is a lot which still can be done like outsorcing the HTML to a template,
137
     * or distinguish between different File Types,
138
     * at the moment we assume the $file is always an (sub-)instance of \Core\File\Entity
139
     *
140
     * @param \Core\View\Helper\InsertFile\FileEvent $e
141
     * @return string
142
     */
143
    public function renderFile(FileEvent $e)
144
    {
145
        $file = $e->getLastFileObject();
146
        // assume it is of the class Core\Entity\FileEntity
147
        $return = '<div class="col-md-3"><a href="#attachment_' . $file->getId() . '">' . $file->getName() . '</a></div>' . PHP_EOL
148
                . '<div class="col-md-3">' . $file->getType() . '</div>'
149
                . '<div class="col-md-3">' . $file->prettySize . '</div>';
150
        /*
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...
151
         * this snippet was for direct inserting an image into the PDF
152
        if ($file && $file instanceOf FileEntity && 0 === strpos($file->getType(), 'image')) {
153
            //$content = $file->getContent();
154
            //$url = 'data:image/' . $file->getType() . ';base64,' . base64_encode ($content);
155
            //$html = '<img src="' . $url . '" >';
156
            $html = '<a href="#1">' . $file->getName() . '</a>';
157
            $e->stopPropagation();
158
            return $html;
159
        }
160
         */
161
        return $return;
162
    }
163
164
    /**
165
     * give a summary of all inserted Files,
166
     * this is for having access to those files in the post-process
167
     * @param \Core\View\Helper\InsertFile\FileEvent|\Zend\View\ViewEvent $e
168
     * @return NULL
169
     */
170
    public function collectFiles(FileEvent $e)
171
    {
172
        $this->appendPDF = array();
173
        $files = $e->getAllFiles();
174
        foreach ($files as $name => $file) {
175
            if (!empty($file) && $file instanceof FileEntity) {
176
                if (0 === strpos($file->getType(), 'image')) {
177
                    $this->appendImage[] = $file;
178
                }
179
                if (strtolower($file->getType()) == 'application/pdf') {
180
                    $this->appendPDF[] = $file;
181
                }
182
            }
183
        }
184
        return null;
185
    }
186
    
187
    /**
188
     * remove unwanted or layout related data
189
     *
190
     * basically you rake through the viewmodel for the data you want to use for your template,
191
     * this may not be optimal because you have to rely on the correct naming of the viewmodels
192
     *
193
     * if you get the data you want, you switch to the specific template by adding the conforming resolver
194
     *
195
     * @param \Zend\View\ViewEvent $e
196
     */
197
    public function cleanLayout(ViewEvent $e)
198
    {
199
        $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...
200
        $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...
201
        $model = $e->getModel();
202
        if ($model->hasChildren()) {
203
            $children = $model->getChildren();
204
            $content = null;
205
            foreach ($children as $child) {
206
                if ($child->captureTo() == 'content') {
207
                    $content = $child;
208
                    $this->attachViewResolver();
209
                }
210
            }
211
            if (!empty($content)) {
212
                $e->setModel($content);
213
            }
214
        } 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...
215
            // attach the own resolver here too ?
216
            // ...
217
        }
218
    }
219
    
220
    /**
221
     * Attach an own ViewResolver
222
     */
223
    public function attachViewResolver()
224
    {
225
        if (!$this->viewResolverAttached) {
226
            $this->viewResolverAttached = true;
227
            $resolver = $this->serviceManager->get('ViewResolver');
228
            $resolver->attach($this, 100);
229
        }
230
    }
231
    
232
    /**
233
     * Transform the HTML to PDF,
234
     * this is a post-rendering-process
235
     *
236
     * put in here everything related to the transforming-process like options
237
     *
238
     * @param \Zend\View\ViewEvent $e
239
     */
240
    public function attachPDFtransformer(ViewEvent $e)
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
241
    {
242
        
243
        //$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...
244
        $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...
245
        $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...
246
        
247
        // the handles are for temporary files
248
        error_reporting(0);
249
        foreach (array(self::RENDER_FULL, self::RENDER_WITHOUT_PDF, self::RENDER_WITHOUT_ATTACHMENTS ) as $render) {
250
            $handles = array();
251
            try {
252
                $pdf = new extern\mPDFderive();
253
                $pdf->SetImportUse();
254
                // create bookmark list in Acrobat Reader
255
                $pdf->h2bookmarks = array('H1' => 0, 'H2' => 1, 'H3' => 2);
256
                $pdf->WriteHTML($result);
257
258
                // Output of the Images
259
                if (self::RENDER_FULL == $render || self::RENDER_WITHOUT_PDF == $render) {
260
                    if (is_array($this->appendImage) && !empty($this->appendImage)) {
261
                        foreach ($this->appendImage as $imageAttachment) {
262
                            $content = $imageAttachment->getContent();
263
                            $url = 'data:image/' . $imageAttachment->getType() . ';base64,' . base64_encode($content);
264
                            $html = '<a name="attachment_' . $imageAttachment->getId() . '"><img src="' . $url . '" /><br /></a>';
265
                            $pdf->WriteHTML($html);
266
                        }
267
                    }
268
                }
269
270
                // Temp Files PDF
271
                if (self::RENDER_FULL == $render) {
272
                    if (is_array($this->appendPDF) && !empty($this->appendPDF)) {
273
                        foreach ($this->appendPDF as $pdfAttachment) {
274
                            $content = $pdfAttachment->getContent();
275
                            $tmpHandle = tmpfile();
276
                            $handles[] = $tmpHandle;
277
                            fwrite($tmpHandle, $content);
278
                            fseek($tmpHandle, 0);
279
                        }
280
                    }
281
                }
282
283
                // Output of the PDF
284
                foreach ($handles as $handle) {
285
                    $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...
286
                    $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...
287
                    $pdf->WriteHTML($filename);
288
                    $pagecount = $pdf->SetSourceFile($filename);
289
                    for ($pages = 0; $pages < $pagecount; $pages++) {
290
                        $pdf->AddPage();
291
                        $pdf->WriteHTML(' pages: ' . $pagecount);
292
                        $tx = $pdf->ImportPage($pages + 1);
293
                        $pdf->UseTemplate($tx);
294
                    }
295
                }
296
297
                $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...
298
                $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...
299
300
                // delete all temporary Files again
301
                foreach ($handles as $handle) {
302
                    fclose($handle);
303
                }
304
                break;
305
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
306
            }
307
        }
308
        error_reporting(E_ALL);
309
    }
310
    
311
    /**
312
     * Look for a template with the Suffix ".pdf.phtml"
313
     *
314
     * @param string $name
315
     * @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...
316
     * @return string|boolean
317
     */
318
    public function resolve($name, Renderer $renderer = null)
319
    {
320
        if ($this->serviceManager->has('ViewTemplatePathStack')) {
321
            // get all the Pases made up for the zend-provided resolver
322
            // we won't get any closer to ALL than that
323
            $viewTemplatePathStack = $this->serviceManager->get('ViewTemplatePathStack');
324
            $paths = $viewTemplatePathStack->getPaths();
325
            $defaultSuffix = $viewTemplatePathStack->getDefaultSuffix();
326
            if (pathinfo($name, PATHINFO_EXTENSION) != $defaultSuffix) {
327
                ;
328
                $name .= '.pdf.' . $defaultSuffix;
329
            } 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...
330
                // TODO: replace Filename by Filename for PDF
331
            }
332
333
            foreach ($paths as $path) {
334
                $file = new SplFileInfo($path . $name);
335
                if ($file->isReadable()) {
336
                    // Found! Return it.
337
                    if (($filePath = $file->getRealPath()) === false && substr($path, 0, 7) === 'phar://') {
338
                        // Do not try to expand phar paths (realpath + phars == fail)
339
                        $filePath = $path . $name;
340
                        if (!file_exists($filePath)) {
341
                            break;
342
                        }
343
                    }
344
                    //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...
345
                    //    // If using a stream wrapper, prepend the spec to the path
346
                    //    $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...
347
                    //}
348
                    return $filePath;
349
                }
350
            }
351
        }
352
        // TODO: Resolving to an PDF has failed, this could have implications for the transformer
353
        return false;
354
    }
355
}
356