Test Failed
Push — master ( 357bf5...71cdad )
by Russell
03:53
created

QueuedExternalContentImporter::process()   B

Complexity

Conditions 11
Paths 9

Size

Total Lines 48
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 28
c 1
b 0
f 1
dl 0
loc 48
rs 7.3166
cc 11
nc 9
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
4
use Symbiote\QueuedJobs\Services\QueuedJob;
5
6
/**
7
 * An abstract class for a content importer that works within the queuedjobs module
8
 *
9
 * @author Marcus Nyeholt <[email protected]>
10
 * @license BSD License http://silverstripe.org/bsd-license
11
 */
12
abstract class QueuedExternalContentImporter extends AbstractQueuedJob
13
{
14
    protected $contentTransforms = array();
15
16
    public function __construct(
17
        $contentItem = null,
18
        $target = null,
19
        $includeParent = false,
20
        $includeChildren = true,
21
        $duplicateStrategy='overwrite',
22
        $params = array()
23
    ) {
24
        if ($contentItem) {
25
            $this->sourceObjectID = $contentItem->ID;
26
            $this->targetObjectID = $target->ID;
27
            $this->targetObjectType = $target->ClassName;
28
            $this->includeParent = $includeParent;
29
            $this->includeChildren = $includeChildren;
30
            $this->duplicateStrategy = $duplicateStrategy;
31
            $this->params = $params;
32
        } else {
33
            // if there's no constructor params, it means we're executing
34
            $this->init();
35
        }
36
    }
37
38
    public function getTitle()
39
    {
40
        if ($this->sourceObjectID) {
41
            $source = ExternalContent::getDataObjectFor($this->sourceObjectID);
42
            return "External Content import from " . $source->Title;
43
        }
44
45
        return 'External content import';
46
    }
47
48
    /**
49
     * By default jobs should just go into the default processing queue
50
     *
51
     * @return String
52
     */
53
    public function getJobType()
54
    {
55
        $sourceObject = ExternalContent::getDataObjectFor($this->sourceObjectID);
56
        if (!$sourceObject) {
57
            $this->addMessage("ERROR: Source object $this->sourceObjectID cannot be found");
58
            return QueuedJob::QUEUED;
59
        }
60
61
        // go a couple levels deep and see how many items we're looking at
62
        if (!$this->includeChildren) {
63
            return QueuedJob::QUEUED;
64
        }
65
66
        $children = $sourceObject->stageChildren();
67
        if (!$children) {
68
            return QueuedJob::QUEUED;
69
        }
70
        $count = 1;
71
72
        foreach ($children as $child) {
73
            $count++;
74
            if ($count > 20) {
75
                $this->totalSteps = $count;
76
                return QueuedJob::QUEUED;
77
            }
78
79
            $subChildren = $child->stageChildren();
80
            if ($subChildren) {
81
                foreach ($subChildren as $sub) {
82
                    $count++;
83
                    if ($count > 20) {
84
                        $this->totalSteps = $count;
85
                        return QueuedJob::QUEUED;
86
                    }
87
                }
88
            }
89
        }
90
        $this->totalSteps = $count;
91
        return QueuedJob::QUEUED;
92
    }
93
94
    /**
95
     * @return array
96
     */
97
    public function getParams()
98
    {
99
        return $this->params;
100
    }
101
102
    /**
103
     */
104
    public function setup()
105
    {
106
        $remainingChildren = array();
107
        if ($this->includeParent) {
108
            $remainingChildren[] = new EC_SourceTarget($this->sourceObjectID, $this->targetObjectID, $this->targetObjectType);
109
        } else {
110
            $sourceObject = ExternalContent::getDataObjectFor($this->sourceObjectID);
111
            if ($sourceObject) {
112
                $children = $sourceObject->stageChildren();
113
                if ($children) {
114
                    foreach ($children as $child) {
115
                        $remainingChildren[] = new EC_SourceTarget($child->ID, $this->targetObjectID, $this->targetObjectType);
116
                    }
117
                }
118
            }
119
        }
120
121
        $this->totalSteps = count($remainingChildren);
122
        $this->remainingChildren = $remainingChildren;
123
    }
124
125
    /**
126
     * Lets process a single node, and collect its children
127
     */
128
    public function process()
129
    {
130
        $remainingChildren = $this->remainingChildren;
131
132
        if (!count($remainingChildren)) {
133
            $this->isComplete = true;
134
            return;
135
        }
136
137
        $this->currentStep++;
138
139
        // lets process our first item
140
        $pair = array_shift($remainingChildren);
141
        $sourceObject = ExternalContent::getDataObjectFor($pair->sourceID);
142
        if (!$sourceObject) {
143
            $this->addMessage("Missing source object for " . $pair->sourceID, 'WARNING');
144
            $this->remainingChildren = $remainingChildren;
145
            return;
146
        }
147
148
        $targetObject = DataObject::get_by_id($pair->targetType, $pair->targetID);
149
        if (!$targetObject) {
150
            $this->addMessage("Missing target object for $pair->targetType $pair->sourceID", 'WARNING');
151
            $this->remainingChildren = $remainingChildren;
152
            return;
153
        }
154
155
        // lets do a single import first, then check the children and append them
156
        $pageType = $this->getExternalType($sourceObject);
157
        if (isset($this->contentTransforms[$pageType])) {
158
            $transformer = $this->contentTransforms[$pageType];
159
160
            $result = $transformer->transform($sourceObject, $targetObject, $this->duplicateStrategy);
161
162
            // if there's more, then transform them
163
            if ($this->includeChildren && $result && $result->children && count($result->children)) {
164
                foreach ($result->children as $child) {
165
                    $remainingChildren[] = new EC_SourceTarget($child->ID, $result->page->ID, $result->page->ClassName);
166
                    $this->totalSteps++;
167
                }
168
            }
169
        }
170
171
        $this->remainingChildren = $remainingChildren;
172
173
        if (!count($remainingChildren)) {
174
            $this->isComplete = true;
175
            return;
176
        }
177
    }
178
179
    /**
180
     * Get the type of the item as far as the remote system
181
     * is concerned. This should match up with what is defined
182
     * in the contentTransforms array
183
     *
184
     * @return string
185
     * 			The type of the ExternalContentItem
186
     */
187
    abstract protected function getExternalType($item);
188
}
189
190
/**
191
 * Tuple class for storing details about future imports when necessary
192
 */
193
class EC_SourceTarget
194
{
195
    public $sourceID;
196
    public $targetID;
197
    public $targetType;
198
199
    public function __construct($sid, $tid, $t)
200
    {
201
        $this->sourceID = $sid;
202
        $this->targetID = $tid;
203
        $this->targetType = $t;
204
    }
205
}
206