Skip to content

Commit f25f73d

Browse files
committed
New sniff to check for BC break in jQuery 1.8
1 parent 920b8a6 commit f25f73d

File tree

5 files changed

+377
-3
lines changed

5 files changed

+377
-3
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
/**
3+
* Ensures that values submitted via JS are not compared to NULL.
4+
*
5+
* PHP version 5
6+
*
7+
* @category PHP
8+
* @package PHP_CodeSniffer_MySource
9+
* @author Greg Sherwood <[email protected]>
10+
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
11+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12+
* @link http://pear.php.net/package/PHP_CodeSniffer
13+
*/
14+
15+
/**
16+
* Ensures that values submitted via JS are not compared to NULL.
17+
*
18+
* jQuery 1.8 changed the behavious of ajax requests so that null values are
19+
* submitted as null= instead of null=null.
20+
*
21+
* @category PHP
22+
* @package PHP_CodeSniffer_MySource
23+
* @author Greg Sherwood <[email protected]>
24+
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
25+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
26+
* @version Release: @package_version@
27+
* @link http://pear.php.net/package/PHP_CodeSniffer
28+
*/
29+
class MySource_Sniffs_PHP_AjaxNullComparisonSniff implements PHP_CodeSniffer_Sniff
30+
{
31+
32+
33+
/**
34+
* Returns an array of tokens this test wants to listen for.
35+
*
36+
* @return array
37+
*/
38+
public function register()
39+
{
40+
return array(T_FUNCTION);
41+
42+
}//end register()
43+
44+
45+
/**
46+
* Processes this sniff, when one of its tokens is encountered.
47+
*
48+
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
49+
* @param int $stackPtr The position of the current token in
50+
* the stack passed in $tokens.
51+
*
52+
* @return void
53+
*/
54+
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
55+
{
56+
$tokens = $phpcsFile->getTokens();
57+
58+
// Make sure it is an API function. We know this by the doc comment.
59+
$commentEnd = $phpcsFile->findPrevious(T_DOC_COMMENT, $stackPtr);
60+
$commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT, ($commentEnd - 1), null, true);
61+
$comment = $phpcsFile->getTokensAsString($commentStart, ($commentEnd - $commentStart));
62+
if (strpos($comment, '* @api') === false) {
63+
return;
64+
}
65+
66+
67+
// Find all the vars passed in as we are only interested in comparisions
68+
// to NULL for these specific variables.
69+
$foundVars = array();
70+
$open = $tokens[$stackPtr]['parenthesis_opener'];
71+
$close = $tokens[$stackPtr]['parenthesis_closer'];
72+
for ($i = ($open + 1); $i < $close; $i++) {
73+
if ($tokens[$i]['code'] === T_VARIABLE) {
74+
$foundVars[] = $tokens[$i]['content'];
75+
}
76+
}
77+
78+
if (empty($foundVars) === true) {
79+
return;
80+
}
81+
82+
$start = $tokens[$stackPtr]['scope_opener'];
83+
$end = $tokens[$stackPtr]['scope_closer'];
84+
for ($i = ($start + 1); $i < $end; $i++) {
85+
if ($tokens[$i]['code'] !== T_VARIABLE
86+
|| in_array($tokens[$i]['content'], $foundVars) === false
87+
) {
88+
continue;
89+
}
90+
91+
$operator = $phpcsFile->findNext(T_WHITESPACE, ($i + 1), null, true);
92+
if ($tokens[$operator]['code'] !== T_IS_IDENTICAL
93+
&& $tokens[$operator]['code'] !== T_IS_NOT_IDENTICAL
94+
) {
95+
continue;
96+
}
97+
98+
$nullValue = $phpcsFile->findNext(T_WHITESPACE, ($operator + 1), null, true);
99+
if ($tokens[$nullValue]['code'] !== T_NULL) {
100+
continue;
101+
}
102+
103+
$error = 'Values submitted via Ajax requests must not be compared directly to NULL; use empty() instead';
104+
$phpcsFile->addError($error, $nullValue, 'Found');
105+
}//end for
106+
107+
108+
}//end process()
109+
110+
111+
}//end class
112+
113+
?>
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<?php
2+
/**
3+
* Adds a new issue.
4+
*
5+
* Returns the new issue id.
6+
*
7+
* @param string $title Title of the new issue.
8+
* @param string $description The description of the issue.
9+
* @param string $reporter Asset id of the reporter.
10+
* @param integer $projectid Id of the project that the issue belongs to.
11+
* @param array $tags Array of tags.
12+
* @param string $status The status of the issue.
13+
* @param string $assignedTo The asset id of the user that the issue is
14+
* assigned to.
15+
* @param string $reportedDate If set then this date will be used instead of the
16+
* current date and time.
17+
* @param integer $reportedMilestone Reported milestone.
18+
*
19+
* @return integer
20+
* @throws ChannelException If there is an error.
21+
*
22+
* @api write
23+
* @api-permission public
24+
*/
25+
public static function addIssue(
26+
$title,
27+
$description,
28+
$reporter=NULL,
29+
$projectid=NULL,
30+
array $tags=array(),
31+
$status=NULL,
32+
$assignedTo=NULL,
33+
$reportedDate=NULL,
34+
$reportedMilestone=NULL
35+
) {
36+
// Get current projectid if not specified.
37+
if ($projectid === NULL) {
38+
Channels::includeSystem('Project');
39+
$projectid = Project::getCurrentProjectId();
40+
Channels::modifyBasket('project', $projectid);
41+
}
42+
43+
Channels::includeSystem('SquizRoadmap');
44+
Channels::includeSystem('Permission');
45+
if (Permission::hasPermission($projectid, 'ideas.contribute') === FALSE) {
46+
throw new ChannelException(_('You do not have permission to contribute idea'));
47+
}
48+
49+
if ($assignedTo !== NULL) {
50+
if (Permission::hasPermission($projectid, 'ideas.edit.details') === FALSE) {
51+
throw new ChannelException(_('You do not have permission to assign user to idea'));
52+
}
53+
54+
if (SquizRoadmap::isVisibleProject($projectid, $assignedTo) === FALSE) {
55+
throw new ChannelException(_('Assigned to user does not have access to issue project.'));
56+
}
57+
}
58+
59+
// Get current user id if not specified.
60+
if ($reporter === NULL) {
61+
Channels::includeSystem('User');
62+
$reporter = User::getCurrentUserid();
63+
Channels::modifyBasket('reporter', $reporter);
64+
}
65+
66+
if (SquizRoadmap::isVisibleProject($projectid, $reporter) === FALSE) {
67+
throw new ChannelException(_('Contributed by user does not have access to issue project.'));
68+
}
69+
70+
// Make sure status is valid.
71+
Channels::includeSystem('SquizRoadmap');
72+
Channels::includeSystem('SquizRoadmapStatus');
73+
if ($status === NULL) {
74+
$statuses = SquizRoadmapStatus::getStatus($projectid);
75+
if (empty($statuses) === TRUE) {
76+
throw new ChannelException(_('No defined statuses in project'));
77+
}
78+
79+
$status = $statuses[0]['status'];
80+
Channels::modifyBasket('status', $status);
81+
} else if (SquizRoadmapStatus::isValidStatus($projectid, $status) === FALSE) {
82+
throw new ChannelException(sprintf(_('Invalid status: %s'), $status));
83+
}
84+
85+
$issueid = DAL::seqNextVal('sq_rdm_issue_seq');
86+
Channels::addToBasket('issueid', $issueid);
87+
88+
if ($reportedDate === NULL) {
89+
include_once 'Libs/String/String.inc';
90+
$reportedDate = String::tsIso8601(time());
91+
Channels::modifyBasket('reportedDate', $reportedDate);
92+
}
93+
94+
$title = trim($title);
95+
Channels::modifyBasket('title', $title);
96+
if (empty($title) === TRUE) {
97+
throw new ChannelException(_('Title cannot be empty'));
98+
}
99+
100+
$description = SquizRoadmap::stripTags(trim($description));
101+
Channels::modifyBasket('description', $description);
102+
if (empty($description) === TRUE) {
103+
throw new ChannelException(_('Description cannot be empty'));
104+
}
105+
106+
try {
107+
DAL::beginTransaction();
108+
109+
$query = DAL::getDALQuery('SquizRoadmapIssue', 'addIssue');
110+
DAL::executeQuery($query);
111+
112+
// Add tags for the new issue.
113+
SquizRoadmapIssue::addIssueTags($issueid, $tags);
114+
115+
// Add reporter and assignee to watch list.
116+
SquizRoadmapIssue::addIssueWatch($issueid, $reporter);
117+
118+
if ($assignedTo !== NULL) {
119+
SquizRoadmapIssue::addIssueWatch($issueid, $assignedTo);
120+
}
121+
122+
SquizRoadmapIssue::clearIssueCache($issueid);
123+
124+
DAL::commit();
125+
} catch (Exception $e) {
126+
DAL::rollBack();
127+
throw new ChannelException($e->getMessage());
128+
}//end try
129+
130+
if ($something === NULL) {
131+
if ($bar !== NULL) {
132+
}
133+
}
134+
135+
return $issueid;
136+
137+
}//end addIssue()
138+
139+
/**
140+
* Adds a new issue.
141+
*
142+
* Returns the new issue id.
143+
*
144+
* @param string $title Title of the new issue.
145+
* @param string $description The description of the issue.
146+
* @param string $reporter Asset id of the reporter.
147+
* @param integer $projectid Id of the project that the issue belongs to.
148+
* @param array $tags Array of tags.
149+
* @param string $status The status of the issue.
150+
* @param string $assignedTo The asset id of the user that the issue is
151+
* assigned to.
152+
* @param string $reportedDate If set then this date will be used instead of the
153+
* current date and time.
154+
* @param integer $reportedMilestone Reported milestone.
155+
*
156+
* @return integer
157+
* @throws ChannelException If there is an error.
158+
*
159+
*/
160+
public static function addIssue(
161+
$title,
162+
$description,
163+
$reporter=NULL,
164+
$projectid=NULL,
165+
array $tags=array(),
166+
$status=NULL,
167+
$assignedTo=NULL,
168+
$reportedDate=NULL,
169+
$reportedMilestone=NULL
170+
) {
171+
// Get current projectid if not specified.
172+
if ($projectid === NULL) {
173+
Channels::includeSystem('Project');
174+
$projectid = Project::getCurrentProjectId();
175+
Channels::modifyBasket('project', $projectid);
176+
}
177+
178+
}//end addIssue()
179+
?>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Unit test class for the AjaxNullComparison sniff.
4+
*
5+
* PHP version 5
6+
*
7+
* @category PHP
8+
* @package PHP_CodeSniffer_MySource
9+
* @author Greg Sherwood <[email protected]>
10+
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
11+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12+
* @link http://pear.php.net/package/PHP_CodeSniffer
13+
*/
14+
15+
/**
16+
* Unit test class for the AjaxNullComparison sniff.
17+
*
18+
* A sniff unit test checks a .inc file for expected violations of a single
19+
* coding standard. Expected errors and warnings are stored in this class.
20+
*
21+
* @category PHP
22+
* @package PHP_CodeSniffer_MySource
23+
* @author Greg Sherwood <[email protected]>
24+
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
25+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
26+
* @version Release: @package_version@
27+
* @link http://pear.php.net/package/PHP_CodeSniffer
28+
*/
29+
class MySource_Tests_PHP_AjaxNullComparisonUnitTest extends AbstractSniffUnitTest
30+
{
31+
32+
33+
/**
34+
* Returns the lines where errors should occur.
35+
*
36+
* The key of the array should represent the line number and the value
37+
* should represent the number of errors that should occur on that line.
38+
*
39+
* @return array(int => int)
40+
*/
41+
public function getErrorList()
42+
{
43+
return array(
44+
37 => 1,
45+
49 => 1,
46+
60 => 1,
47+
73 => 1,
48+
88 => 1,
49+
118 => 1,
50+
);
51+
52+
}//end getErrorList()
53+
54+
55+
/**
56+
* Returns the lines where warnings should occur.
57+
*
58+
* The key of the array should represent the line number and the value
59+
* should represent the number of warnings that should occur on that line.
60+
*
61+
* @return array(int => int)
62+
*/
63+
public function getWarningList()
64+
{
65+
return array();
66+
67+
}//end getWarningList()
68+
69+
70+
}//end class
71+
72+
?>

CodeSniffer/Standards/MySource/ruleset.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
<exclude-pattern>*/Tests/*</exclude-pattern>
66
<exclude-pattern>*/Oven/*</exclude-pattern>
77
<exclude-pattern>*/data/*</exclude-pattern>
8+
<exclude-pattern>*/jquery.js</exclude-pattern>
9+
<exclude-pattern>*/jquery.*.js</exclude-pattern>
10+
<exclude-pattern>*/viper/*</exclude-pattern>
811
<exclude-pattern>DALConf.inc</exclude-pattern>
912

1013
<!-- Include the whole Squiz standard except FunctionComment, which we override -->

0 commit comments

Comments
 (0)