Completed
Pull Request — master (#49)
by
unknown
03:34
created

URLArrayObject::addObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
1
<?php
2
/**
3
 * This is an helper object to StaticPagesQueue to hold an array of urls with
4
 * priorites to be recached.
5
 *
6
 * If the StaticPagesQueue::is_realtime is false this class will call
7
 * StaticPagesQueue::push_urls_to_db when in __destructs.
8
 *
9
 */
10
class URLArrayObject extends ArrayObject {
11
12
	private $shutDownRegistered = false;
13
14
	/**
15
	 * Adds metadata into all URLs in the array.
16
	 *
17
	 * @param $urls array of url => priority
18
	 * @param $obj DataObject to inject
19
	 *
20
	 * @return array array of transformed URLs.
21
	 */
22
	public function addObjects($urls, DataObject $dataObject) {
0 ignored issues
show
Unused Code introduced by
The parameter $dataObject 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...
23
		$processedUrls = array();
24
		foreach ($urls as $url=>$priority) {
25
			if ($url !== false) {
26
				$processedUrls[$url] = $priority;
27
			}
28
		}
29
30
		return $processedUrls;
31
	}
32
33
	/**
34
	 * Extracts the metadata from the queued structure.
35
	 *
36
	 * @param $url string
37
	 *
38
	 * @return DataObject represented by the URL.
39
	 */
40
	public function getObject($url) {
41
		$urlParts = @parse_url($url);
42
		if (isset($urlParts['query'])) parse_str($urlParts['query'], $getParameters);
43
		else $getParameters = array();
44
45
		$obj = null;
46
		if(isset($getParameters['_ID']) && isset($getParameters['_ClassName'])) {
47
			$id = $getParameters['_ID'];
48
			$className = $getParameters['_ClassName'];
49
			$obj = DataObject::get($className)->byID($id);
50
		}
51
52
		return $obj;
53
	}
54
55
	/**
56
	 * Adds urls to the queue after injecting the objects' metadata.
57
	 *
58
	 * @param $urls array associative array of url => priority
59
	 * @param $dataObject DataObject object to associate the urls with
60
	 */
61
	public function addUrlsOnBehalf(array $urls, DataObject $dataObject) {
62
		return $this->addUrls($this->addObjects($urls, $dataObject));
63
	}
64
65
	/**
66
	 * The format of the urls should be array( 'URLSegment' => '50')
67
	 *
68
	 * @param array $urls 
69
	 */
70
	public function addUrls(array $urls) {
71
		if(!$urls) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $urls of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
72
			return;
73
		}
74
		
75
		$urlsAlreadyProcessed = array();    //array to filter out any duplicates
76
		foreach ($urls as $URLSegment=>$priority) {
77
			if(is_numeric($URLSegment) && is_string($priority)) {   //case when we have a non-associative flat array
78
				$URLSegment = $priority;
79
				$priority = 50;
80
			}
81
82
			//only add URLs of a certain length and only add URLs not already added
83
			if (!empty($URLSegment) &&
84
			    strlen($URLSegment) > 0 &&
85
			    !isset($urlsAlreadyProcessed[$URLSegment]) &&
86
				substr($URLSegment,0,4) != "http") {    //URLs isn't to an external site
87
88
				//check to make sure this page isn't excluded from the cache
89
				if (!$this->excludeFromCache($URLSegment)) {
90
					$this->append(array($priority, $URLSegment));
91
				}
92
				$urlsAlreadyProcessed[$URLSegment] = true;  //set as already processed
93
			}
94
		}
95
96
		// Insert into the database directly instead of waiting to destruct time
97
		if (Config::inst()->get('StaticPagesQueue', 'realtime')) {
98
			$this->insertIntoDB();
99
		} else {
100
			//don't register a shutdown twice within a single object
101
			if (!$this->shutDownRegistered) {
102
				register_shutdown_function(array($this,'destructMethod'));
103
				$this->shutDownRegistered = true;
104
			}
105
		}
106
	}
107
108
	protected function excludeFromCache($url) {
109
		$excluded = false;
110
111
		//don't publish objects that are excluded from cache
112
		$candidatePage = SiteTree::get_by_link($url);
113
		if (!empty($candidatePage)) {
114
			if (!empty($candidatePage->excludeFromCache)) {
115
				$excluded = true;
116
			}
117
		}
118
119
		return $excluded;
120
	}
121
122
	/**
123
	 * When this class is getting garbage collected, trigger the insert of all
124
	 * urls into the database
125
	 *
126
	 */
127
	public function destructMethod() {
128
		if (!Config::inst()->get('StaticPagesQueue', 'realtime')) {
129
			$this->insertIntoDB();
130
		}
131
	}
132
133
	/**
134
	 * This method will insert all URLs that exists in this object into the 
135
	 * database by calling the StaticPagesQueue
136
	 *
137
	 * @return type 
138
	 */
139
	public function insertIntoDB() {
140
		$arraycopy = $this->getArrayCopy();
141
		usort($arraycopy, array($this, 'sortOnPriority'));
142
		foreach ($arraycopy as $array) {
143
			StaticPagesQueue::add_to_queue($array[0], $array[1]);
144
		}
145
		StaticPagesQueue::push_urls_to_db();
146
		$this->exchangeArray(array());
147
	}
148
149
	/**
150
	 * Sorts the array on priority, from highest to lowest
151
	 *
152
	 * @param array $a
153
	 * @param array $b
154
	 * @return int - signed
155
	 */
156
	protected function sortOnPriority($a, $b) {
157
		if ($a[0] == $b[0]) {
158
			return 0;
159
		}
160
		return ($a[0] > $b[0]) ? -1 : 1;
161
	}
162
163
	// removes the injected _ID and _ClassName get parameters
164
	public static function sanitize_url($url) {
165
		list($urlPart, $query) = array_pad(explode('?', $url), 2, '');
166
		parse_str($query, $getVars);
167
		unset($getVars['_ID'], $getVars['_ClassName']);
168
		$sanitizedQuery = http_build_query($getVars);
169
		
170
		$sanitizedQuery = ($sanitizedQuery !== '') ? '?' . $sanitizedQuery : '';
171
		return $urlPart . $sanitizedQuery;
172
	}
173
}
174