Completed
Push — master ( a34ca5...70c3fb )
by Simon
01:43
created

PartialSubmissionJob::processSubmissions()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 19
rs 9.2
cc 4
eloc 14
nc 4
nop 3
1
<?php
2
3
namespace Firesphere\PartialUserforms\Jobs;
4
5
use DNADesign\ElementalUserForms\Model\ElementForm;
6
use Firesphere\PartialUserforms\Models\PartialFieldSubmission;
7
use Firesphere\PartialUserforms\Models\PartialFormSubmission;
8
use SilverStripe\Control\Email\Email;
9
use SilverStripe\Dev\Debug;
10
use SilverStripe\ORM\ArrayList;
11
use SilverStripe\ORM\DataList;
12
use SilverStripe\ORM\FieldType\DBDatetime;
13
use SilverStripe\SiteConfig\SiteConfig;
14
use SilverStripe\UserForms\Model\UserDefinedForm;
15
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
16
17
class PartialSubmissionJob extends AbstractQueuedJob
18
{
19
20
    /**
21
     * The generated CSV files
22
     * @var array
23
     */
24
    protected $files = [];
25
26
    protected $config;
27
28
    /**
29
     * @return string
30
     */
31
    public function getTitle()
32
    {
33
        return _t(__CLASS__ . '.Title', 'Export partial submissions to Email');
34
    }
35
36
    /**
37
     * Do some processing yourself!
38
     */
39
    public function process()
40
    {
41
        $this->config = SiteConfig::current_site_config();
42
43
        if (!$this->config->SendDailyEmail || !Email::is_valid_address($this->config->SendMailTo)) {
44
            $this->addMessage('Can not process without valid email');
45
            return;
46
        }
47
48
        /** @var DataList|PartialFormSubmission[] $exportForms */
49
        $allSubmissions = PartialFormSubmission::get()->filter(['IsSend' => false]);
50
        /** @var ArrayList|UserDefinedForm[]|ElementForm[] $parents */
51
        $userDefinedForms = ArrayList::create();
52
        $this->getParents($allSubmissions, $userDefinedForms);
53
54
        /** @var UserDefinedForm $form */
55
        foreach ($userDefinedForms as $form) {
56
            $fileName = _t(__CLASS__ . '.Export', 'Export of ') .
57
                $form->Title . ' - ' .
58
                DBDatetime::now()->Format(DBDatetime::ISO_DATETIME);
59
            $file = '/tmp/' . $fileName . '.csv';
60
            $this->files[] = $file;
61
            $this->buildCSV($file, $form);
62
        }
63
64
        /** @var Email $mail */
65
        $mail = Email::create();
66
67
        $mail->setSubject('Partial form submissions of ' . DBDatetime::now()->Format(DBDatetime::ISO_DATETIME));
68
        foreach ($this->files as $file) {
69
            $mail->addAttachment($file);
70
        }
71
72
        $mail->setTo($this->config->SendMailTo);
73
        $mail->setFrom('[email protected]');
74
        $mail->send();
75
76
        $this->isComplete = true;
77
    }
78
79
    /**
80
     * @param $file
81
     * @param $form
82
     */
83
    protected function buildCSV($file, $form)
84
    {
85
        $resource = fopen($file, 'w+');
86
        /** @var PartialFormSubmission $submissions */
87
        $submissions = PartialFormSubmission::get()->filter(['UserDefinedFormID' => $form->ID]);
88
        $headerFields = $form
89
            ->Fields()
90
            ->exclude(['Name:PartialMatch' => 'EditableFormStep'])
91
            ->column('Title');
92
        fputcsv($resource, $headerFields);
93
94
        if ($submissions->count()) {
0 ignored issues
show
Documentation Bug introduced by
The method count does not exist on object<Firesphere\Partia...\PartialFormSubmission>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
95
            $this->processSubmissions($form, $submissions, $resource);
96
        }
97
        fclose($resource);
98
    }
99
100
    /**
101
     * @param $form
102
     * @param $submissions
103
     * @param $submitted
104
     * @param $resource
105
     */
106
    protected function processSubmissions($form, $submissions, $resource)
107
    {
108
        $editableFields = $form->Fields()->map('Name', 'Title')->toArray();
109
        $submitted = [];
110
        foreach ($submissions as $submission) {
111
            $values = $submission->PartialFields()->map('Name', 'Value')->toArray();
112
            $i = 0;
113
            foreach ($editableFields as $field => $title) {
114
                $submitted[] = '';
115
                if (isset($values[$field])) {
116
                    $submitted[] = $values[$field];
117
                }
118
                $i++;
119
            }
120
            fputcsv($resource, $submitted);
121
            $submission->IsSend = true;
122
            $submission->write();
123
        }
124
    }
125
126
    /**
127
     * @param $allSubmissions
128
     * @param $userDefinedForms
129
     */
130
    protected function getParents($allSubmissions, $userDefinedForms)
131
    {
132
        /** @var PartialFormSubmission $submission */
133
        foreach ($allSubmissions as $submission) {
134
            // Due to having to support Elemental ElementForm, we need to manually get the parent
135
            // It's a bit a pickle, but it works
136
            $parentClass = $submission->ParentClass;
137
            $parent = $parentClass::get()->byID($submission->UserDefinedFormID);
138
            if ($parent &&
139
                $parent->ExportPartialSubmissions &&
140
                !$userDefinedForms->find('ID', $parent->ID)
141
            ) {
142
                $userDefinedForms->push($parent);
143
            }
144
            $submission->destroy();
145
        }
146
    }
147
148
    public function afterComplete()
149
    {
150
        parent::afterComplete();
151
        if ($this->config->CleanupAfterSend) {
152
            /** @var DataList|PartialFormSubmission[] $forms */
153
            $forms = PartialFormSubmission::get()->filter(['IsSend' => true]);
154
            foreach ($forms as $form) {
155
                /** @var DataList|PartialFieldSubmission[] $fields */
156
                $fields = PartialFieldSubmission::get()->filter(['ID' => $form->PartialFields()->column('ID')]);
157
                $fields->removeAll();
158
                $form->delete();
159
                $form->destroy();
160
            }
161
        }
162
//        if ($this->config->)
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
163
    }
164
165
    public function getMessages()
166
    {
167
        return $this->messages;
168
    }
169
}
170