This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | |||
4 | abstract class SocialIntegrationControllerBaseClass extends Controller |
||
0 ignored issues
–
show
|
|||
5 | { |
||
6 | |||
7 | /** |
||
8 | * default profile pic in case none is available |
||
9 | * @var String |
||
10 | */ |
||
11 | private static $default_avatar = "http://placeholder.it/32x32"; |
||
12 | public static function get_default_avatar() |
||
13 | { |
||
14 | return self::$default_avatar; |
||
15 | } |
||
16 | public static function set_default_avatar($s) |
||
17 | { |
||
18 | self::$default_avatar = $s; |
||
19 | } |
||
20 | |||
21 | /** |
||
22 | * tells us if a class is a Social Integration API class (e.g. Facebook, Twiiter, etc....) |
||
23 | * @param String $className |
||
24 | * @return Boolean |
||
25 | */ |
||
26 | public static function is_social_integration_api_class($className) |
||
27 | { |
||
28 | if (class_exists($className)) { |
||
29 | $arrayOfInterfacesItImplements = class_implements($className); |
||
30 | if (is_array($arrayOfInterfacesItImplements) && in_array("SocialIntegrationAPIInterface", $arrayOfInterfacesItImplements)) { |
||
31 | return true; |
||
32 | } |
||
33 | } |
||
34 | return false; |
||
35 | } |
||
36 | |||
37 | |||
38 | /** |
||
39 | * one stop shop button |
||
40 | * @return Object ( |
||
41 | * IsConnected, |
||
42 | * IsLoggedIn, |
||
43 | * Link, |
||
44 | * ConnectedName, |
||
45 | * ConnectedImageURL |
||
46 | * ) |
||
47 | */ |
||
48 | public static function get_login_button($backURL = "", $member) |
||
0 ignored issues
–
show
get_login_button uses the super-global variable $_SERVER which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() Parameters which have default values should be placed at the end.
If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway: // $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
![]() |
|||
49 | { |
||
50 | //back URL |
||
51 | if (!$backURL) { |
||
52 | $backURL = $_SERVER['REQUEST_URI']; |
||
53 | } |
||
54 | $position = strpos($backURL, "?"); |
||
55 | if ($position) { |
||
56 | $backURL = substr($backURL, 0, $position); |
||
57 | } |
||
58 | $backURL = str_replace("//", "/", $backURL); |
||
59 | $backURL .= "#".strtolower(self::my_service_name())."_tab"; |
||
60 | $backURL = "?BackURL=".urlencode($backURL); |
||
61 | //security |
||
62 | $token = SecurityToken::inst(); |
||
63 | if ($member->exists()) { |
||
64 | //AJAX FUNCTIONALITY |
||
65 | //Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js'); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
46% 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. ![]() |
|||
66 | //Requirements::javascript(THIRDPARTY_DIR . '/jquery-livequery/jquery.livequery.js'); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
46% 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. ![]() |
|||
67 | //Requirements::javascript('social_integration/javascript/'.strtolower(self::my_service_name()).".js"); |
||
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. ![]() |
|||
68 | $method = "has".self::my_service_name(); |
||
69 | if ($member->$method()) { |
||
70 | $removeURL = Controller::join_links(self::my_class_name(), 'remove', $backURL); |
||
71 | $removeURL = $token->addToUrl($removeURL); |
||
72 | $nameField = self::my_service_name()."Name"; |
||
73 | $pictureField = self::my_service_name()."Picture"; |
||
74 | return new ArrayData( |
||
75 | array( |
||
76 | "IsConnected" => true, |
||
77 | "IsLoggedIn" => Member::currentUserID() == $member->ID ? true : false, |
||
78 | "Link" => $removeURL, |
||
79 | "ConnectedName" => $member->$nameField, |
||
80 | "ConnectedImageURL" => $member->$pictureField |
||
81 | ) |
||
82 | ); |
||
83 | } else { |
||
84 | $connectURL = Controller::join_links(self::my_class_name(), self::my_service_name().'Connect', $backURL); |
||
85 | $connectURL = $token->addToUrl($connectURL); |
||
86 | return new ArrayData( |
||
87 | array( |
||
88 | "IsConnected" => false, |
||
89 | "IsLoggedIn" => Member::currentUserID() == $member->ID ? true : false, |
||
90 | "Link" => $connectURL, |
||
91 | "ConnectedName" => "", |
||
92 | "ConnectedImageURL" => "" |
||
93 | ) |
||
94 | ); |
||
95 | } |
||
96 | } else { |
||
97 | $connectURL = Controller::join_links(self::my_class_name(), self::my_service_name().'Connect', $backURL); |
||
98 | $connectURL = $token->addToUrl($connectURL); |
||
99 | return new ArrayData( |
||
100 | array( |
||
101 | "IsConnected" => false, |
||
102 | "IsLoggedIn" => false, |
||
103 | "Link" => $connectURL, |
||
104 | "ConnectedName" => "", |
||
105 | "ConnectedImageURL" => "" |
||
106 | ) |
||
107 | ); |
||
108 | } |
||
109 | } |
||
110 | |||
111 | |||
112 | /** |
||
113 | * @param String $returnURL |
||
114 | * @return String |
||
115 | */ |
||
116 | public static function login_url($returnURL = "") |
||
117 | { |
||
118 | $backURLString = ""; |
||
119 | if ($returnURL) { |
||
120 | $backURLString = '?BackURL='.urlencode($returnURL); |
||
121 | } |
||
122 | return 'Security/login/'.$backURLString.'#'.self::my_security_form().'_LoginForm_tab'; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Link to login form |
||
127 | * @param String $returnURL |
||
128 | * @return String |
||
129 | */ |
||
130 | public static function connect_url($returnURL = "", $existingMember = false) |
||
131 | { |
||
132 | $backURLString = ""; |
||
133 | if ($returnURL) { |
||
134 | $backURLString = '?BackURL='.urlencode($returnURL); |
||
135 | } |
||
136 | $method = self::my_service_name()."Connect"; |
||
137 | $className = self::my_class_name(); |
||
138 | return $className."/".$method."/".$backURLString; |
||
139 | } |
||
140 | |||
141 | |||
142 | /** |
||
143 | * redirects to login prompt, lets the user log in and returns to |
||
144 | * the returnURL specified. |
||
145 | * @param String $returnURL |
||
146 | * @return REDIRECTS! |
||
0 ignored issues
–
show
The doc-type
REDIRECTS! could not be parsed: Unknown type name "REDIRECTS!" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
147 | */ |
||
148 | public static function redirect_to_login_prompt($returnURL = "") |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
149 | { |
||
150 | $className = self::my_class_name(); |
||
151 | return self::curr()->redirect($className::login_url($returnURL)); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * The class being called |
||
156 | * (e.g. FacebookCallback::my_class_name should return FacebookCallback) |
||
157 | * @return String |
||
158 | */ |
||
159 | protected static function my_class_name() |
||
160 | { |
||
161 | return get_called_class(); |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * The current ClassName without the "Callback" portion. |
||
166 | * @return String |
||
167 | */ |
||
168 | protected static function my_service_name() |
||
169 | { |
||
170 | return str_replace("Callback", "", self::my_class_name()); |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * The name of the security form. |
||
175 | * @return String |
||
176 | */ |
||
177 | protected function my_security_form() |
||
178 | { |
||
179 | return self::my_class_name()."LoginForm"; |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * returns Absolute URL to a link within this controller, |
||
184 | * by default it is the "Connect" link, because this controller |
||
185 | * always needs an action. |
||
186 | * @return String |
||
187 | */ |
||
188 | public function Title() |
||
189 | { |
||
190 | return self::my_service_name(); |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * returns Absolute URL to a link within this controller, |
||
195 | * by default it is the "Connect" link, because this controller |
||
196 | * always needs an action. |
||
197 | * @return String |
||
198 | */ |
||
199 | public function AbsoluteLink($action = "") |
||
200 | { |
||
201 | if (!$action) { |
||
202 | $action = $this->serviceName."Connect"; |
||
0 ignored issues
–
show
The property
serviceName does not exist on object<SocialIntegrationControllerBaseClass> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
203 | } |
||
204 | return Director::absoluteURL($this->Link($action)); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * returns relative URL to a link within this controller, |
||
209 | * by default it is the "Connect" link, because this controller |
||
210 | * always needs an action. |
||
211 | * @return String |
||
212 | */ |
||
213 | public function Link($action = "") |
||
214 | { |
||
215 | if (!$action) { |
||
216 | $action = $this->serviceName."Connect"; |
||
0 ignored issues
–
show
The property
serviceName does not exist on object<SocialIntegrationControllerBaseClass> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
217 | } |
||
218 | $className = self::my_class_name(); |
||
219 | return self::join_links($className, $action); |
||
220 | } |
||
221 | |||
222 | public static function is_valid_user($screen_name) |
||
223 | { |
||
224 | return true; |
||
225 | } |
||
226 | |||
227 | |||
228 | //========================================== HELPER METHODS ===================================== |
||
229 | |||
230 | public function __construct() |
||
231 | { |
||
232 | parent::__construct(); |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * you need to add an action |
||
237 | */ |
||
238 | public function index() |
||
239 | { |
||
240 | if (Director::isDev()) { |
||
241 | return $this->renderWith(array("SocialIntegrationControllerBaseClass")); |
||
242 | } else { |
||
243 | die("For security reasons, this service works in DEV move only."); |
||
0 ignored issues
–
show
The method
index() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
244 | } |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * works out best Return URL |
||
249 | * @param Boolean $hasAbsoluteBaseURL - should it include the Base URL (e.g. http://www.mysite.com) |
||
250 | * @return String |
||
251 | */ |
||
252 | protected function returnURL($hasAbsoluteBaseURL = false) |
||
253 | { |
||
254 | $returnURL = "/Security/login/"; |
||
255 | if (!empty($this->requestParams["BackURL"])) { |
||
256 | $returnURL = $this->requestParams["BackURL"]; |
||
257 | } elseif (Session::get("BackURL")) { |
||
258 | $returnURL = Session::get("BackURL"); |
||
259 | Session::set("BackURL", ""); |
||
260 | Session::clear("BackURL"); |
||
261 | } |
||
262 | $returnURL = urldecode($returnURL); |
||
263 | if ($hasAbsoluteBaseURL) { |
||
264 | $returnURL = Director::absoluteBaseURL().$returnURL; |
||
265 | } |
||
266 | return $returnURL; |
||
267 | } |
||
268 | |||
269 | public function Tests() |
||
270 | { |
||
271 | if (Director::isDev()) { |
||
272 | $dos = new DataObjectSet(); |
||
273 | $tests = array( |
||
274 | "connect" => "connect to this service", |
||
275 | "login" => "do a traditional log in to this service", |
||
276 | "meonservice" => "what details does this service know about me right now, retrieve from service", |
||
277 | "meondatabase" => "what data is stored with current member", |
||
278 | "updates" => "show my latest updates", |
||
279 | "friends" => "get a list of my friends (or the equivalent (e.g. followers))", |
||
280 | "friendssearch" => "????", |
||
281 | "isvaliduser" => "????", |
||
282 | "sendmessage" => "test sending a message", |
||
283 | "remove" => "remove this service from my account" |
||
284 | ); |
||
285 | foreach ($tests as $test => $description) { |
||
286 | $dos->push( |
||
287 | new ArrayData( |
||
0 ignored issues
–
show
new \ArrayData(array('Li.... ': ' . $description)) is of type object<ArrayData> , but the function expects a object<DataObject> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
288 | array( |
||
289 | "Link" => "/".$this->Link("test/".$test."/"), |
||
290 | "Name" => "<strong>".$test."</strong>".": ".$description |
||
291 | ) |
||
292 | ) |
||
293 | ); |
||
294 | } |
||
295 | return $dos; |
||
296 | } |
||
297 | return null; |
||
298 | } |
||
299 | |||
300 | |||
301 | public function menondatabase() |
||
302 | { |
||
303 | //to be completed |
||
304 | } |
||
305 | |||
306 | public function test($request) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
307 | { |
||
308 | $className = self::my_class_name(); |
||
309 | $testType = $request->param("ID"); |
||
310 | $IDField = self::my_service_name()."ID"; |
||
311 | echo "<h2>TEST: $testType</h2><pre>"; |
||
312 | switch ($testType) { |
||
313 | case "connect": |
||
314 | return $this->connectUser("/$className/test/meonservice/"); |
||
0 ignored issues
–
show
The method
connectUser does not exist on object<SocialIntegrationControllerBaseClass> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when 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 { }
![]() |
|||
315 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
316 | case "login": |
||
317 | print_r($className::redirect_to_login_prompt("/$className/test/meonservice/")); |
||
318 | break; |
||
319 | case "meonservice": |
||
320 | $outcome = $className::get_current_user(); |
||
321 | if (!$outcome) { |
||
322 | echo "NOT CONNECTED"; |
||
323 | } else { |
||
324 | print_r($outcome); |
||
325 | } |
||
326 | break; |
||
327 | case "meondatabase": |
||
328 | $this->meondatabase(); |
||
0 ignored issues
–
show
The method
meondatabase() does not exist on SocialIntegrationControllerBaseClass . Did you maybe mean menondatabase() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise. ![]() |
|||
329 | break; |
||
330 | case "updates": |
||
331 | print_r($className::get_updates()); |
||
332 | break; |
||
333 | case "friends": |
||
334 | print_r($className::get_list_of_friends(-1)); |
||
335 | break; |
||
336 | case "friendssearch": |
||
337 | print_r($className::get_list_of_friends(-1, "john")); |
||
338 | break; |
||
339 | case "isvaliduser": |
||
340 | $member = Member::currentUser(); |
||
341 | if ($member) { |
||
342 | if (self::my_service_name() == "Twitter") { |
||
343 | $IDField = "TwitterID"; |
||
344 | } |
||
345 | $id = $member->$IDField; |
||
346 | } else { |
||
347 | $id = ""; |
||
348 | } |
||
349 | print_r($className::is_valid_user($id)); |
||
350 | break; |
||
351 | case "sendmessage": |
||
352 | $member = Member::currentUser(); |
||
353 | $otherVariables = array(); |
||
354 | if ($member) { |
||
355 | if (self::my_service_name() == "Facebook") { |
||
356 | $otherVariables = array( |
||
357 | "name" => "test name", |
||
358 | "caption" => "test caption", |
||
359 | "description" => "test description" |
||
360 | ); |
||
361 | } |
||
362 | $fieldName = self::my_service_name()."ID"; |
||
363 | $outcome = $className::send_message( |
||
364 | $member->$fieldName, |
||
365 | $message = "message goes here", |
||
366 | $link = "http://www.google.com", |
||
367 | $otherVariables |
||
368 | ); |
||
369 | } else { |
||
370 | $outcome = "You must be logged in to send a message."; |
||
371 | } |
||
372 | echo " |
||
373 | <h1>Sending message to yourself</h1> |
||
374 | <p>OUTCOME: <pre>...$outcome</pre>"; |
||
375 | break; |
||
376 | case "remove": |
||
377 | $method = "Remove".self::my_service_name(); |
||
378 | echo $this->$method(null); |
||
379 | break; |
||
380 | default: |
||
381 | echo "no test to run"; |
||
382 | } |
||
383 | echo "</pre><hr /><a href=\"/$className\">back to test index</a>"; |
||
384 | } |
||
385 | } |
||
386 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.