GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (88)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

lib/hooks.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Elgg\CommunityPlugins;
4
use PluginProject;
5
use PluginRelease;
6
use ElggUser;
7
use ElggMenuItem;
8
9
/**
10
 * Prepare a notification message about a new plugin project or a new plugin release
11
 *
12
 * @param string                          $hook         Hook name
13
 * @param string                          $type         Hook type
14
 * @param Elgg_Notifications_Notification $notification The notification to prepare
15
 * @param array                           $params       Hook parameters
16
 * @return Elgg_Notifications_Notification
17
 */
18
function prepare_notification($hook, $type, $notification, $params) {
19
	$entity = $params['event']->getObject();
20
	$owner = $params['event']->getActor();
21
	$recipient = $params['recipient'];
22
	$language = $params['language'];
23
	$method = $params['method'];
24
25
	$subtype = $entity->getSubtype();
26
	if ($subtype == 'plugin_project') {
27
		$text = $entity->description;
28
	} else {
29
		$text = $entity->release_notes;
30
	}
31
32
	// Notification title
33
	$notification->subject = elgg_echo("plugins:{$subtype}:notify:subject", array($owner->name, $entity->title), $language);
34
35
	// Notification body
36
	$notification->body = elgg_echo("plugins:{$subtype}:notify:body", array(
37
	    $owner->name,
38
	    $entity->title,
39
	    $text,
40
	    $entity->getURL()
41
	), $language);
42
43
	// Notification summary
44
	$notification->summary = elgg_echo("plugins:{$subtype}:notify:summary", array($entity->title), $language);
45
46
	return $notification;
47
}
48
49
50
/**
51
 * Get notification subscriptions for a new plugin release
52
 *
53
 * The Elgg 1.9 subscriptions system is based on containers. By default it is
54
 * possible to subscribe only to users. The container of a release is however
55
 * a project, so we need to get subscriptions for the project when notifying
56
 * about a new release.
57
 *
58
 * @param string $hook          Hook name
59
 * @param string $type          Hook type
60
 * @param array  $subscriptions Array of subscriptions
61
 * @param array  $params        Hook parameters
62
 * @return array $subscriptions
63
 */
64
function get_release_subscriptions($hook, $type, $subscriptions, $params) {
65
	$entity = $params['event']->getObject();
66
67
	if ($entity instanceof PluginRelease) {
68
		$project = $entity->getContainerEntity();
69
70
		// We skip the first release because we notify about the new plugin project instead
71
		if ($project->getReleases(array('count' => true)) > 1) {
72
			$subscriptions += elgg_get_subscriptions_for_container($project->container_guid);
73
		}
74
	}
75
76
	return $subscriptions;
77
}
78
79
80
/**
81
 * Releases are owned by the plugin, so this hook is needed for non-admins
82
 * To have edit permission on their releases.  Release is editable if the
83
 * Plugin is editable.
84
 * 
85
 * @param type $h
86
 * @param type $t
87
 * @param type $r
88
 * @param array $p
89
 * @return bool
90
 */
91
function release_permissions_check($h, $t, $r, $p) {
92
	if (!($p['entity'] instanceof PluginRelease)) {
93
		return $r;
94
	}
95
	
96
	$project = $p['entity']->getContainerEntity();
97
	return $project->canEdit();
98
}
99
100
101
/**
102
 * Add a menu item to the owner block
103
 *
104
 * @param string $hook   'register'
105
 * @param string $type   'menu:owner_block'
106
 * @param array  $menu   Array of ElggMenu object
107
 * @param array  $params Hook patameters
108
 * @return array $menu Array of ElggMenu object
109
 */
110
function owner_block_menu($hook, $type, $menu, $params) {
111
	$user = $params['entity'];
112
113
	if (!$user instanceof ElggUser) {
114
		return $menu;
115
	}
116
	
117
	if (elgg_in_context('plugins')) {
118
		return array(); // owner block menu causes clutter on these pages
119
	}
120
	
121
	$url = "plugins/search?owner={$user->username}";
122
	$item = new ElggMenuItem('plugins', elgg_echo('plugins'), $url);
123
	$menu[] = $item;
124
125
	return $menu;
126
}
127
128
129
/**
130
 * Populates the ->getUrl() method for plugin releases
131
 * Redirects to the project page.
132
 *
133
 * @param string $hook
134
 * @param string $type
135
 * @param string $url
136
 * @param array  $params
137
 * @return string
138
 */
139
function release_url_handler($hook, $type, $url, $params) {
140
	$release = $params['entity'];
141
142
	if (!$release instanceof PluginRelease) {
143
		return $url;
144
	}
145
146
	$project = $release->getProject();
147
	if (!$project) {
148
		error_log("Community plugins: unable to access project for release $release->guid");
149
		return $url;
150
	}
151
152
	$version = rawurlencode($release->version);
153
	return  "/plugins/$project->guid/releases/$version";
154
}
155
156
157
/**
158
 * Handles plugin project URLs
159
 *
160
 * @param string $hook
161
 * @param string $type
162
 * @param string $url
163
 * @param array  $params
164
 * @return string
165
 */
166
function project_url_handler($hook, $type, $url, $params) {
167
	$project = $params['entity'];
168
169
	if (!$project instanceof PluginProject) {
170
		return $url;
171
	}
172
173
    return "/plugins/$project->guid";
174
}
175
176
177
/**
178
 * Add menu items for the ownership_request annotation
179
 *
180
 * @param string $hook
181
 * @param string $type
182
 * @param string $menu
183
 * @param array  $params
184
 * @return array $menu
185
 */
186
function ownership_request_menu($hook, $type, $menu, $params) {
187
	$annotation = elgg_extract('annotation', $params);
188
189
	if ($annotation->name !== 'ownership_request') {
190
		return $menu;
191
	}
192
193
	$menu[] = ElggMenuItem::factory(array(
194
		'name' => 'approve_ownership_request',
195
		'text' => elgg_echo('approve'),
196
		'href' => "action/plugins/admin/transfer?project_guid={$annotation->entity_guid}&members[]={$annotation->owner_guid}",
197
		'link_class' => 'elgg-button elgg-button-action',
198
		'is_action' => true,
199
	));
200
201
	return $menu;
202
}
203
204
205
/**
206
 * Plugin project search hook
207
 *
208
 * @param string $hook
209
 * @param string $type
210
 * @param <type> $value
211
 * @param <type> $params
212
 * @return array
213
 */
214
function search_hook($hook, $type, $value, $params) {
215
	global $CONFIG;
216
	$query = sanitise_string($params['query']);
217
218
	$join = "JOIN {$CONFIG->dbprefix}objects_entity oe ON e.guid = oe.guid";
219
	$params['joins'] = array($join);
220
	$params['joins'][] = "JOIN {$CONFIG->dbprefix}metadata summary_md on e.guid = summary_md.entity_guid";
221
	$params['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings summary_msn on summary_md.name_id = summary_msn.id";
222
	$params['joins'][] = "JOIN {$CONFIG->dbprefix}metastrings summary_msv on summary_md.value_id = summary_msv.id";
223
224
	$fields = array('title', 'description');
225
	$where = search_get_where_sql('oe', $fields, $params);
226
227
	// cheat and use LIKE for the summary field
228
	// this is kinda dirty.
229
	$likes = array();
230
	$query_arr = explode(' ', $query);
231
	foreach ($query_arr as $word) {
232
		$likes[] = "summary_msv.string LIKE \"%$word%\"";
233
	}
234
	$like_str = implode(' OR ', $likes);
235
236
	//$params['wheres'] = array("($where OR ($like_str))");
237
	$params['wheres'] = array($where);
238
239
//	If metastrings were fulltext'd we could do this :(
240
//	$select = "summary_msv.string summary_string";
241
//	$params['selects'] = array($select);
242
//
243
//	$fields = array('string');
244
//	$summary_where = search_get_where_sql('summary_msv', $fields, $params);
245
//	$params['wheres'][] = $summary_where;
246
247
	if (($category = get_input('category')) && ($category != 'all')) {
248
		$params['metadata_name_value_pair'] = array ('name' => 'plugincat', 'value' => $category, 'case_sensitive' => FALSE);
249
	}
250
	$params['order_by'] = search_get_order_by_sql('e', 'oe', $params['sort'], $params['order']);
251
252
253
	$entities = elgg_get_entities_from_metadata($params);
254
	$params['count'] = TRUE;
255
	$count = elgg_get_entities_from_metadata($params);
256
257
	// no need to continue if nothing here.
258
	if (!$count) {
259
		return array('entities' => array(), 'count' => $count);
260
	}
261
262
	// add the volatile data for why these entities have been returned.
263
	foreach ($entities as $entity) {
264
		$title = search_get_highlighted_relevant_substrings($entity->title, $params['query']);
265
		$entity->setVolatileData('search_matched_title', $title);
266
267
		$desc = search_get_highlighted_relevant_substrings($entity->summary, $params['query']);
268
		$entity->setVolatileData('search_matched_description', $desc);
269
	}
270
271
	return array(
272
		'entities' => $entities,
273
		'count' => $count,
274
	);
275
}
276
277
278
/**
279
 * Nightly update on download counts
280
 *
281
 * Adds 1.2M to the figure to account for downloads before this system as implemented.
282
 */
283
function update_download_counts() {
284
	$options = array(
285
		'type' => 'object',
286
		'subtype' => 'plugin_release',
287
		'annotation_name' => 'download',
288
		'count' => true,
289
	);
290
	$count = elgg_get_annotations($options);
291
	$count += 1200000;
292
	elgg_set_plugin_setting('site_plugins_downloads', $count, 'community_plugins');
293
}
294
295
296
function project_comments($hook, $type, $return, $params) {
297
	if (elgg_instanceof($params['entity'], 'object', 'plugin_project')) {
298
		return false;
299
	}
300
	
301
	return $return;
302
}
303
304
/**
305
 * Setup head <meta> tags for plugin projects
306
 *
307
 * @param string $hook   "head"
308
 * @param string $type   "page"
309
 * @param array  $return Head params
310
 * @param array  $params Hook params
311
 * @return array
312
 */
313
function prepare_page_head_meta($hook, $type, $return, $params) {
0 ignored issues
show
The parameter $hook 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...
The parameter $type 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...
314
315
	$entity = elgg_extract('entity', $params);
316
317
	if (!$entity instanceof \PluginProject) {
318
		return;
319
	}
320
321
	$tags = (array) $entity->tags;
322
	if (!empty($tags)) {
323
		$return['metas']['keywords'] = [
324
			'name' => 'keywords',
325
			'content' => implode(', ', $tags),
326
		];
327
	}
328
329
	$owner = $entity->getOwnerEntity();
330
	if ($owner) {
331
		$return['metas']['author'] = [
332
			'name' => 'author',
333
			'content' => $owner->getDisplayName(),
334
		];
335
	}
336
337
	$summary = $entity->summary ? : $entity->desription;
338
	if ($summary) {
339
		$summary = elgg_get_excerpt($summary);
340
		$return['metas']['description'] = [
341
			'name' => 'description',
342
			'content' => $summary,
343
		];
344
345
		$return['metas']['og:description'] = [
346
			'property' => 'og:description',
347
			'content' => $summary
348
		];
349
	}
350
351
	$return['metas']['og:type'] = [
352
		'property' => 'og:type',
353
		'content' => 'article',
354
	];
355
	$return['metas']['og:title'] = [
356
		'property' => 'og:title',
357
		'content' => $entity->getDisplayName(),
358
	];
359
360
	$return['metas']['og:url'] = [
361
		'property' => 'og:url',
362
		'content' => $entity->getURL(), // set canonical URL for release pages
363
	];
364
365
	$screenshots = $entity->getScreenshots();
366
	if ($screenshots) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $screenshots 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...
367
		$i = 0;
368
		foreach ($screenshots as $screenshot) {
369
			$thumb = get_entity($screenshot->thumbnail_guid);
370
			if (!$thumb) {
371
				continue;
372
			}
373
			$return['metas']["og:image:$i"] = [
374
				'property' => 'og:image',
375
				'content' => elgg_normalize_url("plugins/icon/$screenshot->guid/icon.jpg"),
376
			];
377
			$i++;
378
		}
379
	}
380
381
	return $return;
382
}
383