Completed
Push — develop ( eb5f8c...2537a4 )
by
unknown
13:09
created

Module   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 325
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 10

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 47
c 1
b 0
f 0
lcom 2
cbo 10
dl 0
loc 325
rs 8.439

How to fix   Complexity   

Complex Class

Complex classes like Module often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Module, and based on these observations, apply Extract Interface, too.

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) {
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)
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
        /*
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();
200
        $response = $e->getResponse();
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 {
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)
241
    {
242
        
243
        //$renderer = $e->getRenderer();
244
        $result   = $e->getResult();
245
        $response = $e->getResponse();
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);
286
                    $filename = $meta_data["uri"];
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();
298
                $e->setResult($pdf_result);
299
300
                // delete all temporary Files again
301
                foreach ($handles as $handle) {
302
                    fclose($handle);
303
                }
304
                break;
305
            } catch (\Exception $e) {
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
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 {
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()) {
345
                    //    // If using a stream wrapper, prepend the spec to the path
346
                    //    $filePath = 'zend.view://' . $filePath;
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