Completed
Push — master ( d21053...c59b30 )
by
unknown
08:11
created

tempFilestore   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 6
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
wmc 1
lcom 0
cbo 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A make_file_matrix() 0 3 1
1
<?php
2
/**
3
 * Tidypics file plugin migration
4
 *
5
 * Supports moving photos from the files plugin to Tidypics. All of a users
6
 * photos end up in a single album.
7
 *
8
 * Not supported
9
 */
10
11
// need access to ElggDiskFilestore::make_file_matrix(), which is protected.
12
// this is a PITA.
13
class tempFilestore extends ElggDiskFilestore {
14
	public function make_file_matrix($filename) {
15
		return parent::make_file_matrix($filename);
0 ignored issues
show
Deprecated Code introduced by
The method ElggDiskFilestore::make_file_matrix() has been deprecated with message: 1.8 Use \Elgg\EntityDirLocator

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
16
	}
17
18
}
19
$filestore = new tempFilestore();
20
21
22
23
/**
24
 * Migrates all pics from files to tidypics.
25
 *
26
 */
27
function tidypics_migrate_pics() {
28
	$limit = 100;
29
	$r = true;
30
31
	// migrate
32
	// @todo: should this return false since there was no error?
33
	if (!$users = tidypics_get_user_guids_with_pics_in_files(0, $limit)) {
34
		return $r;
35
	}
36
37
	//echo "Grabbed " . count($users) . " users\n";
38
	while (is_array($users) AND count($users) > 0) {
39
		foreach ($users as $user_guid) {
40
			// reset the query cache.
41
			$DB_QUERY_CACHE = array();
42
			if (!$user = get_entity($user_guid)) {
43
				continue;
44
			}
45
46
			$r = tidypics_migrate_user_pics($user);
0 ignored issues
show
Compatibility introduced by
$user of type object<ElggEntity> is not a sub-type of object<ElggUser>. It seems like you assume a child class of the class ElggEntity to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
47
		}
48
49
		//echo "Trying to grab $limit more users...\n";
50
		$offset = $offset + $limit;
0 ignored issues
show
Bug introduced by
The variable $offset does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
51
		$users = tidypics_get_user_guids_with_pics_in_files($offset, $limit);
52
	}
53
54
	return $r;
55
}
56
57
58
/**
59
 * Migrates all pictures owned by a user regardless of
60
 * if they're group or user files.
61
 *
62
 * @param ElggUser $user User to migrate.
63
 * @return bool on success
64
 */
65
function tidypics_migrate_user_pics(ElggUser $user) {
66
	global $filestore;
67
68
	$user_guid = $user->getGUID();
69
70
	// update all entity subtypes in a single go at the end.
71
	$updated_guids = array();
72
73
	if (!$pics = tidypics_get_user_pics_from_files($user_guid) OR count($pics) < 1) {
74
		return false;
75
	}
76
77
	//echo "{$user->name} ({$user->getGUID()}) has " . count($pics) . " pics.\n";
78
79
	// get an album to migrate into if it already exists.
80
	// will create later on if it doesn't.
81
	$user_album_entities = elgg_get_entities_from_metadata(array('metadata_name' => 'migrated_from_files',
82
                                                                     'metadata_value' => true,
83
	                                                             'type' => 'object',
84
	                                                             'subtype' => 'album',
85
	                                                             'owner_guid' => $user->getGUID(),
86
	                                                             'limit' => 1));
87
	
88
	$user_album_guid = isset($album_entities[0]) ? $album_entities[0]->getGUID() : false;
0 ignored issues
show
Bug introduced by
The variable $album_entities does not exist. Did you mean $user_album_entities?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
89
90
	// a list of albums to randomly select a cover for on newly created albums.
91
	$new_album_guids = array();
92
93
	foreach ($pics as $pic) {
94
		// check that it's not already in tidy pics
95
		if (false !== strpos($pic->filename, 'image/')) {
96
			//echo "{$pic->filename} ({$pic->getGUID()}) looks like it's already in tidy pics. Ignoring.\n";
97
			continue;
98
		}
99
100
		// blank some vars
101
		$group_pic = $group_album_guid = $group_guid = false;
102
103
		// see if we're doing a group file migration.
104
		if ($pic->container_guid != $user->getGUID()
105
			AND $group = get_entity($pic->container_guid)
106
			AND $group instanceof ElggGroup
107
		) {
108
			//echo "{$pic->getGUID()} is in a group!\n";
109
			$group_pic = true;
110
			$group_guid = $group->getGUID();
111
112
			// yes, this is how you get entities by container_guid.
113
			// yes, it's wrong, wrong, wrong for this function to work this way.
114
			$group_album_entities = elgg_get_entities(array('type' => 'object', 'subtype' => 'album',  'owner_guid' => $group_guid));
115
116
			// get_entities_from_metadata doesn't support container_guid (or owner_guid meaning container_guid)
117
			// do it the hard way.
118
			if (is_array($group_album_entities)) {
119
				foreach ($group_album_entities as $group_album) {
120
					if ($group_album->migrated_from_files == true) {
121
						$group_album_guid = $group_album->getGUID();
122
						break;
123
					}
124
				}
125
			}
126
			$album_guid = $group_album_guid;
127
			$group_album_guids[] = $group_album_guid;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$group_album_guids was never initialized. Although not strictly required by PHP, it is generally a good practice to add $group_album_guids = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
128
		} else {
129
			$album_guid = $user_album_guid;
130
		}
131
132
		//echo "album_guid is $album_guid and group_pic is: $group_pic\n";
133
134
		// create an album if we need to.
135
		if (!$album_guid) {
136
			//echo "Creating new album...\n";
137
			$album = new ElggObject();
138
			$album->subtype = 'album';
139
			$album->new_album = TP_NEW_ALBUM;
140
141
			if ($group_pic) {
142
				$album->container_guid = $group_guid;
143
				$album->owner_guid = $group->owner_guid;
0 ignored issues
show
Bug introduced by
The variable $group does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
144
				$album->access_id = $group->group_acl;
145
				$album->title = $group->name;
146
			} else {
147
				$album->container_guid = $user_guid;
148
				$album->owner_guid = $user->getGUID();
149
				$album->access_id = ACCESS_DEFAULT;
150
				$album->title = $user->name;
151
			}
152
153
			if (!$album->save()) {
154
				//echo "Couldn't migrate pics for {$user->name} ($user_guid)!\n";
155
				return false;
156
			}
157
			$album->migrated_from_files = true;
158
			$album_guid = $album->getGUID();
159
			$new_album_guids[] = $album_guid;
160
161
			// save the album guid as the users
162
			if (!$group_pic) {
163
				$user_album_guid = $album_guid;
164
			}
165
		}
166
167
		if (!tidypics_migrate_pic_from_files($pic, $album_guid)) {
168
			//echo "{$pic->filename} ({$pic->getGUID()}) Couldn't be migrated. Ignoring.\n";
169
			continue;
170
		}
171
	}
172
173
	// randomly pic an image to be the cover for the user gallery
174
	//$album->cover = $pic_guids[array_rand($pic_guids)];
175
	foreach ($new_album_guids as $guid) {
176
		tidypics_set_random_cover_pic($guid);
177
	}
178
179
	return true;
180
}
181
182
183
/**
184
 * Randomly pics an image from an album to be the cover.
185
 * @return bool on success
186
 */
187
function tidypics_set_random_cover_pic($album_guid) {
188
	$db_prefix = elgg_get_config('dbprefix');
189
190
	if ($album = get_entity($album_guid) AND $album instanceof TidypicsAlbum) {
191
		$q = "SELECT guid FROM {$db_prefix}entities WHERE container_guid = $album_guid ORDER BY RAND() limit 1";
192
		$pic = get_data($q);
193
194
		return $album->cover = $pic[0]->guid;
195
	}
196
197
	return false;
198
}
199
200
/**
201
 * Migrates a single pic from the file repo.
202
 * @return bool on succes.
203
 */
204
function tidypics_migrate_pic_from_files($pic, $album_guid) {
205
	global $filestore;
206
207
	// get the subtype id.
208
	$image_subtype_id = get_subtype_id('object', 'image');
209
210
	// hold which metadata on the files need to be changes
211
	// also holds the images we need to move
212
	$file_md_fields = array('filename', 'thumbnail', 'smallthumb', 'largethumb');
213
214
	if (!$user = get_entity($pic->owner_guid)) {
215
		return false;
216
	}
217
218
	// figure out where to move the files.
219
	$matrix = $filestore->make_file_matrix($user->username);
220
	$user_fs_path = elgg_get_data_path() . $matrix;
221
	$album_fs_path = elgg_get_data_path() . $matrix . "image/$album_guid/";
222
	if (!is_dir($album_fs_path)) {
223
		if (!mkdir($album_fs_path, 0700, true)) {
224
			return false;
225
		}
226
	}
227
228
	// change all the 'file/'s to 'image/'s in certain metadata
229
	// these are also the files we need to move.
230
	foreach ($file_md_fields as $md_name) {
231
		// $pic->$md_name = str_replace('file/', 'image/', $pic->$md_name);
232
		$old_file = $pic->$md_name;
233
		$new_file = str_replace('file/', "image/$album_guid", $old_file);
234
235
		if (!($old_fp = fopen($user_fs_path . $old_file, 'r')
236
		AND $new_fp = fopen($user_fs_path . $new_file, 'w'))) {
237
			//echo "Could not move {$user_fs_path}{$old_file} to {$user_fs_path}{$new_file}\n";
238
			continue;
239
		}
240
241
		while (!feof($old_fp)) {
242
			if (!fputs($new_fp, fread($old_fp, 8192))) {
0 ignored issues
show
Bug introduced by
The variable $new_fp does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
243
				//echo "Could not move {$user_fs_path}{$old_file} to {$user_fs_path}{$new_file} (Error writing.)\n";
244
				break;
245
			}
246
		}
247
248
		$pic->$md_name = $new_file;
249
	}
250
	// update container.
251
	// this doesn't work...?
252
	//$pic->container_guid = $album_guid;
253
254
	// delete old one.
255
	unlink($user_fs_path . $old_file);
0 ignored issues
show
Bug introduced by
The variable $old_file does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
256
257
	$db_prefix = elgg_get_config('dbprefix');
258
	$q = "UPDATE {$db_prefix}entities SET subtype = $image_subtype_id, container_guid = $album_guid WHERE guid = {$pic->getGUID()}";
259
	//echo "Finished moving {$user_fs_path}{$old_file} to {$user_fs_path}{$new_file}\n";
260
261
	return update_data($q);
262
}
263
264
265
/**
266
 * Grabs all user IDs with images in the files repo.
267
 * return mixed. False on fail, array of GUIDs on success.
268
 */
269
function tidypics_get_user_guids_with_pics_in_files($offset, $limit) {
270
	$db_prefix = elgg_get_config('dbprefix');
271
272
	//$simpletype_ms_id = add_metastring('simple_type');
273
	//$image_ms_id = add_metastring('image');
274
275
	$q = "SELECT DISTINCT e.owner_guid
276
		FROM
277
			{$db_prefix}entities as e,
278
			{$db_prefix}entity_subtypes as st
279
280
		WHERE st.subtype = 'file'
281
		AND e.subtype = st.id
282
		LIMIT $offset, $limit";
283
284
	if (!$data = get_data($q)) {
285
		return false;
286
	}
287
288
	// return an array of IDs
289
	$r = array();
290
	foreach ($data as $row) {
291
		$r[] = $row->owner_guid;
292
	}
293
294
	return $r;
295
}
296
297
/**
298
 * Gets a list of images for a single user.
299
 * @return array of GUIDs, false on fail.
300
 */
301
function tidypics_get_user_pics_from_files($user_guid) {
302
	if (!$user = get_entity($user_guid) AND $user instanceof ElggUser) {
303
		return false;
304
	}
305
306
	// @todo Might have to cycle this through with standard while + foreach.
307
	return elgg_get_entities_from_metadata(array('metadata_name' => 'simpletype',
308
                                                     'metadata_value' => 'image',
309
                                                     'type' => 'object',
310
                                                     'subtype' => 'file',
311
                                                     'owner_guid' => $user_guid,
312
                                                     'limit' => 5000));
313
}
314