Best Gherkin-php code snippet using Token.getTokenValue
QueryParser.php
Source:QueryParser.php
...366 }367 // TYPEOF sobject WHEN ... THEN ... [ELSE]368 elseif($this->tokenizer->is(TokenType::KEYWORD))369 {370 $keyword = strtoupper($this->tokenizer->getTokenValue());371 switch($keyword)372 {373 case 'TYPEOF':374 $this->tokenizer->readNextToken(); // ADVANCE TO "WHEN"375 $expression = $this->parseSelectTypeofExpression();376 // EXPECT "END", ADVANCE TO "FROM"-CLAUSE377 $this->tokenizer->expectKeyword('end');378 break;379 default:380 throw new ParseException(sprintf('Unexpected keyword "%s", expecting "TYPEOF", "LEFT_PAREN" or "FIELDNAME".', $keyword), $this->tokenizer->getLine(), $this->tokenizer->getLinePos(), $this->tokenizer->getInput());381 }382 }383 // "ORDINARY" FIELD OR FUNCTION384 elseif($this->tokenizer->isExpressionOrKeyword('from'))385 {386 $name = $this->tokenizer->getTokenValue();387 $this->tokenizer->readNextToken();388 // IS (AGGREGATE) FUNCTION389 if($this->tokenizer->is(TokenType::LEFT_PAREN))390 {391 $expression = new AST\SelectFunction($this->parseFunctionExpression($name, Functions\SoqlFunctionInterface::CONTEXT_SELECT));392 }393 else394 {395 $expression = new AST\SelectField($name);396 }397 }398 // IS THE NEXT TOKEN AN ALIAS?399 if($this->tokenizer->is(TokenType::EXPRESSION) && $expression instanceof AST\CanHazAliasInterface)400 {401 $expression->setAlias($this->parseAlias());402 }403 return $expression;404 }405 /**406 * @return \Codemitte\ForceToolkit\Soql\AST\FromPart407 */408 private function parseFrom()409 {410 $this->tokenizer->expectKeyword('FROM');411 return $this->parseFromField();412 }413 /**414 * @return \Codemitte\ForceToolkit\Soql\AST\FromPart415 */416 private function parseFromField()417 {418 $retVal = new AST\FromPart($this->tokenizer->getTokenValue());419 $this->tokenizer->readNextToken();420 // HAS ALIAS421 if($this->tokenizer->isExpressionOrKeyword(array(422 'where',423 'with',424 'group',425 'having',426 'order',427 'limit',428 'offset'429 ))) {430 $retVal->setAlias($this->parseAlias());431 }432 return $retVal;433 }434 /**435 * @return \Codemitte\ForceToolkit\Soql\AST\Alias436 */437 private function parseAlias()438 {439 if($this->tokenizer->isTokenValue('as'))440 {441 $this->tokenizer->expect(TokenType::EXPRESSION);442 }443 $alias = $this->tokenizer->getTokenValue();444 $this->tokenizer->expect(TokenType::EXPRESSION);445 return new AST\Alias($alias);446 }447 /**448 * CONDITIONEXPR ::= ANDEXPR | OREXPR | NOTEXPR | SIMPLEEXPR449 * ANDEXPR ::= 'AND' SIMPLEEXPR450 * OREXPR ::= 'OR' SIMPLEEXPR451 * NOTEXPR ::= 'NOT' SIMPLEEXPR452 * SIMPLEEXPR ::= '(' CONDITIONEXPR ')' | FIELDEXPR | SETEXPR453 * FIELDEXPR ::= NAME OPERATOR VALUE454 * SETEXPR ::= ( NAME ('includes' | 'excludes' | 'in' | 'not' 'in') '(' VALUE (',' VALUE)* ')' | QUERY)455 * VALUE ::= STRING_LITERAL | NUMBER | DATE | DATETIME | NULL | TRUE | FALSE | DATEFORMULA456 * OPERATOR ::= '=' | '!=' | '<' | '<=' | '>' | '>=' | 'like'457 * LOGICALOPERATOR ::= 'AND' | 'OR ' | 'NOT'458 * DATEFORMULA ::= TODAY | TOMORROW | LAST_WEEK | THIS_WEEK | NEXT_WEEK | THIS_MONTH459 * | LAST_MONTH | NEXT_MONTH | LAST_90_DAYS | NEXT_90_DAYS | LAST_N_DAYS ':' NUMBER460 * | NEXT_N_DAYS ':' NUMBER461 *462 * @return WherePart463 */464 private function parseWhereConditionExpression()465 {466 $this->tokenizer->expectKeyword('where');467 return new AST\WherePart($this->parseWhereLogicalGroup());468 }469 /**470 * // A <OP> 'B'471 * // A <OP> 1214472 * // A <OP> 2011-02-17473 * // A <OP> 2011-02-17474 * // IN[]()475 * // NOT IN[ ]()476 * // includes, excludes477 *478 * @return LogicalGroup479 */480 private function parseWhereLogicalGroup()481 {482 $retVal = new AST\LogicalGroup();483 $retVal->addAll($this->parseWhereLogicalConditions());484 return $retVal;485 }486 /**487 * @return array<LogicalJunction>488 */489 private function parseWhereLogicalConditions()490 {491 $retVal = array();492 $precedingOperator = null;493 while(true)494 {495 $junction = new AST\LogicalJunction();496 $junction->setOperator($precedingOperator);497 // NOT498 if(499 $this->tokenizer->is(TokenType::EXPRESSION) &&500 $this->tokenizer->isTokenValue('not')) {501 $junction->setIsNot(true);502 $this->tokenizer->readNextToken();503 }504 // COND AUF505 if($this->tokenizer->is(TokenType::LEFT_PAREN))506 {507 $this->tokenizer->readNextToken();508 // RECURSE ... returns LogicalGroup509 $junction->setCondition($this->parseWhereLogicalGroup());510 $this->tokenizer->expect(TokenType::RIGHT_PAREN);511 }512 // a=b,513 // dateFunction(a) = b514 // dateFunction(convertTimezone(a)) <= b515 // a=b516 // a IN|INCLUDES|EXCLUDES (a,b,c)517 // NOT a IN|INCLUDES|EXCLUDES (a,b,c)518 // a NOT IN (a,b,c)519 // a NOT IN(SELECT ...)520 // NOT a = b521 // NOT a IN b522 // a LIKE b523 // NOT a LIKE b524 else525 {526 // PARSE "x=y?" structure527 $junction->setCondition($this->parseWhereSimpleCondition());528 }529 $retVal[] = $junction;530 // VERKNÃPFUNG UND VERNEINUNG ...531 if($this->tokenizer->is(TokenType::EXPRESSION))532 {533 if($this->tokenizer->isTokenValue('or'))534 {535 $precedingOperator = AST\LogicalJunction::OP_OR;536 $this->tokenizer->readNextToken();537 continue;538 }539 elseif($this->tokenizer->isTokenValue('and'))540 {541 $precedingOperator = AST\LogicalJunction::OP_AND;542 $this->tokenizer->readNextToken();543 continue;544 }545 }546 break;547 }548 // WHERE PART549 return $retVal;550 }551 /**552 * VORSICHT:553 * Account[] accs = [SELECT Id FROM Account WHERE Name NOT IN ('hans') LIMIT 1]; // geht!554 * Account[] accs = [SELECT Id FROM Account WHERE NOT Name IN ('hans') LIMIT 1]; // geht!555 * Account[] accs = [SELECT Id FROM Account WHERE Name NOT LIKE ('hans') LIMIT 1]; // ERROR!556 * Account[] accs = [SELECT Id FROM Account WHERE NOT Name LIKE ('hans') LIMIT 1]; // geht!557 *558 * // a=b,559 * // a=b560 * // NOT a IN|INCLUDES|EXCLUDES (a,b,c)561 * // a IN|INCLUDES|EXCLUDES (a,b,c)562 * // a NOT IN (a,b,c)563 * // a NOT IN(SELECT ...)564 * // NOT a = b565 * // NOT a IN b566 * // a LIKE b567 * // NOT a LIKE b568 *569 * @throws ParseException570 * @return LogicalCondition571 */572 private function parseWhereSimpleCondition()573 {574 $retVal = new AST\LogicalCondition();575 $retVal->setLeft($this->parseWhereConditionLeft());576 $retVal->setOperator($this->parseWhereOperator());577 $retVal->setRight($this->parseWhereConditionRight());578 return $retVal;579 }580 /**581 * @return AST\WhereFieldInterface582 * @throws ParseException583 */584 private function parseWhereConditionLeft()585 {586 $name = $this->tokenizer->getTokenValue();587 // FUNCTION OR PLAIN VALUE588 $this->tokenizer->expect(TokenType::EXPRESSION);589 // DATE OR GEOLOCATION FUNCTION (DISTANCE/GEOLOCATION)590 if($this->tokenizer->is(TokenType::LEFT_PAREN))591 {592 return new AST\WhereFunction($this->parseFunctionExpression($name, Functions\SoqlFunctionInterface::CONTEXT_WHERE));593 }594 // REGULAR IDENTIFIER595 return new AST\WhereField($name);596 }597 /**598 * @return string599 */600 private function parseWhereOperator()601 {602 // OPERATOR603 $operator = $this->tokenizer->getTokenValue();604 // NOT IN ...605 if('NOT' === $operator)606 {607 $this->tokenizer->readNextToken();608 $operator .= ' ' . $this->tokenizer->getTokenValue();609 }610 $this->tokenizer->readNextToken();611 return $operator;612 }613 /**614 * WHERE RIGHT MIGHT BE:615 * - SUBQUERY616 * - PLAIN/PRIMITIVE VALUE617 * - COLLECTION618 * - VARIABLE619 * @return \Codemitte\ForceToolkit\Soql\AST\ComparableInterface620 */621 private function parseWhereConditionRight()622 {623 $retVal = null;624 if($this->tokenizer->is(TokenType::LEFT_PAREN))625 {626 $this->tokenizer->readNextToken();627 if($this->tokenizer->isKeyword('select'))628 {629 // CREATE SUBQUERY630 $retVal = new AST\Subquery($this->parseQuery());631 }632 else633 {634 // COLLECTION635 $retVal = $this->parseCollectionValue();636 }637 $this->tokenizer->expect(TokenType::RIGHT_PAREN);638 }639 elseif($this->tokenizer->is(TokenType::COLON))640 {641 $retVal = $this->parseNamedVariable();642 }643 elseif($this->tokenizer->is(TokenType::QUESTION_MARK))644 {645 $retVal = $this->parseAnonVariable();646 }647 // EXPRESSION648 else649 {650 $retVal = $this->parsePrimitiveValue();651 }652 return $retVal;653 }654 /**655 * // A <OP> 'B'656 * // A <OP> 1214657 * // A <OP> 2011-02-17658 * // A <OP> 2011-02-17659 *660 * @return LogicalGroup661 */662 private function parseHavingLogicalGroup()663 {664 $retVal = new AST\LogicalGroup();665 $retVal->addAll($this->parseHavingLogicalConditions());666 return $retVal;667 }668 /**669 * @return array<LogicalJunction>670 */671 private function parseHavingLogicalConditions()672 {673 $retVal = array();674 $precedingOperator = null;675 while(true)676 {677 $junction = new AST\LogicalJunction();678 $junction->setOperator($precedingOperator);679 // NOT680 if(681 $this->tokenizer->is(TokenType::EXPRESSION) &&682 $this->tokenizer->isTokenValue('not')) {683 $junction->setIsNot(true);684 $this->tokenizer->readNextToken();685 }686 // COND AUF687 if($this->tokenizer->is(TokenType::LEFT_PAREN))688 {689 $this->tokenizer->readNextToken();690 // RECURSE ... returns LogicalGroup691 $junction->setCondition($this->parseHavingLogicalGroup());692 $this->tokenizer->expect(TokenType::RIGHT_PAREN);693 }694 // a=b,695 // dateFunction(a) = b696 // dateFunction(convertTimezone(a)) <= b697 // a=b698 // a IN|INCLUDES|EXCLUDES (a,b,c)699 // NOT a IN|INCLUDES|EXCLUDES (a,b,c)700 // a NOT IN (a,b,c)701 // NOT a = b702 // NOT a IN b703 // a LIKE b704 // NOT a LIKE b705 else706 {707 // PARSE "x=y?" structure708 $junction->setCondition($this->parseHavingSimpleCondition());709 }710 $retVal[] = $junction;711 // VERKNÃPFUNG UND VERNEINUNG ...712 if($this->tokenizer->is(TokenType::EXPRESSION))713 {714 if($this->tokenizer->isTokenValue('or'))715 {716 $precedingOperator = AST\LogicalJunction::OP_OR;717 $this->tokenizer->readNextToken();718 continue;719 }720 elseif($this->tokenizer->isTokenValue('and'))721 {722 $precedingOperator = AST\LogicalJunction::OP_AND;723 $this->tokenizer->readNextToken();724 continue;725 }726 }727 break;728 }729 // WHERE PART730 return $retVal;731 }732 /**733 * VORSICHT:734 * Account[] accs = [SELECT Id FROM Account WHERE Name NOT IN ('hans') LIMIT 1]; // geht!735 * Account[] accs = [SELECT Id FROM Account WHERE NOT Name IN ('hans') LIMIT 1]; // geht!736 * Account[] accs = [SELECT Id FROM Account WHERE Name NOT LIKE ('hans') LIMIT 1]; // ERROR!737 * Account[] accs = [SELECT Id FROM Account WHERE NOT Name LIKE ('hans') LIMIT 1]; // geht!738 *739 * // a=b,740 * // a=b741 * // NOT a IN|INCLUDES|EXCLUDES (a,b,c)742 * // a IN|INCLUDES|EXCLUDES (a,b,c)743 * // a NOT IN (a,b,c)744 * // NOT a = b745 * // NOT a IN b746 * // a LIKE b747 * // NOT a LIKE b748 *749 * @throws ParseException750 * @return LogicalCondition751 */752 private function parseHavingSimpleCondition()753 {754 $retVal = new AST\LogicalCondition();755 $retVal->setLeft($this->parseHavingConditionLeft());756 $retVal->setOperator($this->parseHavingOperator());757 $retVal->setRight($this->parseHavingConditionRight());758 return $retVal;759 }760 /**761 * @return AST\HavingFieldInterface762 * @throws ParseException763 */764 private function parseHavingConditionLeft()765 {766 $name = $this->tokenizer->getTokenValue();767 // FUNCTION OR PLAIN VALUE768 $this->tokenizer->expect(TokenType::EXPRESSION);769 // DATE OR GEOLOCATION FUNCTION (DISTANCE/GEOLOCATION)770 if($this->tokenizer->is(TokenType::LEFT_PAREN))771 {772 return new AST\HavingFunction($this->parseFunctionExpression($name, Functions\SoqlFunctionInterface::CONTEXT_HAVING));773 }774 // REGULAR IDENTIFIER775 return new AST\HavingField($name);776 }777 private function parseHavingOperator()778 {779 // OPERATOR780 $operator = $this->tokenizer->getTokenValue();781 // NOT IN ...782 if('NOT' === $operator)783 {784 $this->tokenizer->readNextToken();785 $operator .= ' ' . $this->tokenizer->getTokenValue();786 }787 $this->tokenizer->readNextToken();788 return $operator;789 }790 private function parseHavingConditionRight()791 {792 $retVal = null;793 if($this->tokenizer->is(TokenType::LEFT_PAREN))794 {795 $this->tokenizer->readNextToken();796 // COLLECTION797 $retVal = $this->parseCollectionValue();798 $this->tokenizer->expect(TokenType::RIGHT_PAREN);799 }800 elseif($this->tokenizer->is(TokenType::COLON))801 {802 $retVal = $this->parseNamedVariable();803 }804 elseif($this->tokenizer->is(TokenType::QUESTION_MARK))805 {806 $retVal = $this->parseAnonVariable();807 }808 // EXPRESSION809 else810 {811 $retVal = $this->parsePrimitiveValue();812 }813 return $retVal;814 }815 /**816 * @return \Codemitte\ForceToolkit\Soql\AST\WithPart817 */818 private function parseWithFilteringExpression()819 {820 $this->tokenizer->expectKeyword('with');821 // WITH DATA CATEGORY?822 if($this->tokenizer->isKeyword('data'))823 {824 $this->tokenizer->readNextToken();825 $this->tokenizer->expectKeyword('category');826 return new AST\WithPart($this->parseWithDataCategoryLogicalGroup());827 }828 return new AST\WithPart($this->parseWithLogicalGroup());829 }830 private function parseWithLogicalGroup()831 {832 $retVal = new AST\LogicalGroup();833 $retVal->addAll($this->parseWithLogicalConditions());834 return $retVal;835 }836 /**837 * The WITH clause is used in a SELECT statement to filter records based on field values.838 * Unlike the WHERE clause which only supports fields from the object specified in the FROM clause,839 * WITH allows you to filter by other related criteria. For example, you can use the WITH clause to840 * filter articles based on their classification in one or more data category groups. The WITH clause841 * can only be used in the following cases:842 * To filter records based on their categorization. See WITH DATA CATEGORYfilteringExpression.843 * To query and retrieve record changes tracked in a user profile feed. See UserProfileFeed in the844 * Object Reference for Salesforce and Force.com.845 * @return array846 */847 private function parseWithLogicalConditions()848 {849 $retVal = array();850 $precedingOperator = null;851 while(true)852 {853 $junction = new AST\LogicalJunction();854 $junction->setOperator($precedingOperator);855 // NOT856 if(857 $this->tokenizer->is(TokenType::EXPRESSION) &&858 $this->tokenizer->isTokenValue('not')) {859 $junction->setIsNot(true);860 $this->tokenizer->readNextToken();861 }862 // COND AUF863 if($this->tokenizer->is(TokenType::LEFT_PAREN))864 {865 $this->tokenizer->readNextToken();866 // RECURSE ... returns LogicalGroup867 $junction->setCondition($this->parseWithLogicalGroup());868 $this->tokenizer->expect(TokenType::RIGHT_PAREN);869 }870 // a=b,871 // dateFunction(a) = b872 // dateFunction(convertTimezone(a)) <= b873 // a=b874 // a IN|INCLUDES|EXCLUDES (a,b,c)875 // NOT a IN|INCLUDES|EXCLUDES (a,b,c)876 // a NOT IN (a,b,c)877 // a NOT IN(SELECT ...)878 // NOT a = b879 // NOT a IN b880 // a LIKE b881 // NOT a LIKE b882 else883 {884 // PARSE "x=y?" structure885 $junction->setCondition($this->parseWithSimpleCondition());886 }887 $retVal[] = $junction;888 // VERKNÃPFUNG UND VERNEINUNG ...889 if($this->tokenizer->is(TokenType::EXPRESSION))890 {891 if($this->tokenizer->isTokenValue('or'))892 {893 $precedingOperator = AST\LogicalJunction::OP_OR;894 $this->tokenizer->readNextToken();895 continue;896 }897 elseif($this->tokenizer->isTokenValue('and'))898 {899 $precedingOperator = AST\LogicalJunction::OP_AND;900 $this->tokenizer->readNextToken();901 continue;902 }903 }904 break;905 }906 // WHERE PART907 return $retVal;908 }909 private function parseWithSimpleCondition()910 {911 $retVal = new AST\LogicalCondition();912 $retVal->setLeft($this->parseWithConditionLeft());913 $retVal->setOperator($this->parseWithOperator());914 $retVal->setRight($this->parseWithConditionRight());915 return $retVal;916 }917 private function parseWithConditionLeft()918 {919 $name = $this->tokenizer->getTokenValue();920 // FUNCTION OR PLAIN VALUE921 $this->tokenizer->expect(TokenType::EXPRESSION);922 // REGULAR IDENTIFIER923 return new AST\WithField($name);924 }925 private function parseWithOperator()926 {927 // OPERATOR928 $operator = $this->tokenizer->getTokenValue();929 // NOT IN ...930 if('NOT' === $operator)931 {932 $this->tokenizer->readNextToken();933 $operator .= ' ' . $this->tokenizer->getTokenValue();934 }935 $this->tokenizer->readNextToken();936 return $operator;937 }938 private function parseWithConditionRight()939 {940 $retVal = null;941 if($this->tokenizer->is(TokenType::LEFT_PAREN))942 {943 $this->tokenizer->readNextToken();944 if($this->tokenizer->isKeyword('select'))945 {946 // CREATE SUBQUERY947 $retVal = new AST\Subquery($this->parseQuery());948 }949 else950 {951 // COLLECTION952 $retVal = $this->parseCollectionValue();953 }954 $this->tokenizer->expect(TokenType::RIGHT_PAREN);955 }956 elseif($this->tokenizer->is(TokenType::COLON))957 {958 $retVal = $this->parseNamedVariable();959 }960 elseif($this->tokenizer->is(TokenType::QUESTION_MARK))961 {962 $retVal = $this->parseAnonVariable();963 }964 // EXPRESSION965 else966 {967 $retVal = $this->parsePrimitiveValue();968 }969 return $retVal;970 }971 /**972 * @return LogicalGroup973 * @throws ParseException974 */975 private function parseWithDataCategoryLogicalGroup()976 {977 $retVal = new AST\LogicalGroup();978 $retVal->addAll($this->parseWithDataCategoryConditions());979 return $retVal;980 }981 /**982 * @return array983 * @throws ParseException984 */985 private function parseWithDataCategoryConditions()986 {987 $retVal = array();988 $precedingOperator = null;989 while(true)990 {991 $junction = new AST\LogicalJunction();992 $junction->setOperator($precedingOperator);993 // NEW LOGICAL GROUP994 if($this->tokenizer->is(TokenType::LEFT_PAREN))995 {996 $this->tokenizer->readNextToken();997 $junction->setCondition($this->parseWithLogicalGroup());998 $this->tokenizer->expect(TokenType::RIGHT_PAREN);999 }1000 else1001 {1002 // RIGHT1003 $junction->setCondition($condition = new AST\LogicalCondition());1004 // ONLY SIMPLE EXPRESSION ALLOWED1005 $condition->setLeft(new AST\WithField($this->tokenizer->getTokenValue()));1006 // ADVANCE ...1007 $this->tokenizer->expect(TokenType::EXPRESSION);1008 // ABOVE, BELOW, AT, ABOVE_OR_BELOW1009 $operator = $this->tokenizer->getTokenValue();1010 $uppercaseOperator = strtoupper($operator);1011 $oldLine = $this->tokenizer->getLine();1012 $oldPos = $this->tokenizer->getLinePos();1013 $condition->setOperator($operator);1014 $this->tokenizer->expect(TokenType::KEYWORD);1015 if(in_array($uppercaseOperator, self::$DATA_CATEGORY_COMPARISON_OPERATORS))1016 {1017 // (field1, field2) | fieldname1018 $condition->setRight($this->parseWithDataCategoryRightCondition());1019 }1020 else1021 {1022 throw new ParseException(sprintf('Unexpected operator "%s"', $operator), $oldLine, $oldPos, $this->tokenizer->getInput());1023 }1024 }1025 $retVal[] = $junction;1026 // You can only use the AND logical operator. The following syntax is incorrect as OR is not supported:1027 if($this->tokenizer->is(TokenType::EXPRESSION) && $this->tokenizer->isTokenValue('AND'))1028 {1029 $precedingOperator = AST\LogicalJunction::OP_AND;1030 $this->tokenizer->readNextToken();1031 continue;1032 }1033 break;1034 }1035 return $retVal;1036 }1037 /**1038 * @return \Codemitte\ForceToolkit\Soql\AST\ComparableInterface1039 */1040 private function parseWithDataCategoryRightCondition()1041 {1042 $retVal = null;1043 // COLLECTION1044 if($this->tokenizer->is(TokenType::LEFT_PAREN))1045 {1046 $retVal = new AST\SoqlValueCollection();1047 $this->tokenizer->readNextToken();1048 while(true)1049 {1050 $retVal->addValue($this->parseWithDataCategoryRightConditionField());1051 if($this->tokenizer->is(TokenType::COMMA))1052 {1053 $this->tokenizer->readNextToken();1054 continue;1055 }1056 break;1057 }1058 $this->tokenizer->expect(TokenType::RIGHT_PAREN);1059 }1060 // EXPRESSION1061 else1062 {1063 $retVal = $this->parseWithDataCategoryRightConditionField();1064 }1065 return $retVal;1066 }1067 private function parseWithDataCategoryRightConditionField()1068 {1069 $name = $this->tokenizer->getTokenValue();1070 $this->tokenizer->expect(TokenType::EXPRESSION);1071 return new AST\SoqlExpression($name);1072 }1073 /**1074 * @return \Codemitte\ForceToolkit\Soql\AST\ComparableInterface|SoqlValue|SoqlValueCollection1075 */1076 private function parseValue()1077 {1078 $retVal = null;1079 // IS COL1080 if($this->tokenizer->is(TokenType::LEFT_PAREN))1081 {1082 $this->tokenizer->readNextToken();1083 $retVal = $this->parseCollectionValue();1084 $this->tokenizer->expect(TokenType::RIGHT_PAREN);1085 }1086 else1087 {1088 $retVal = $this->parsePrimitiveValue();1089 }1090 return $retVal;1091 }1092 /**1093 * POINTER IS AT FIRST ENTRY OF COLLECTION (MAY BE COLLECTION ITSELF?)1094 *1095 * @return AST\SoqlValueCollection1096 */1097 private function parseCollectionValue()1098 {1099 $retVal = new AST\SoqlValueCollection();1100 while(true)1101 {1102 $retVal->addValue($this->parseValue());1103 // NACH NEM KOMMA GEHTS WEITER1104 if($this->tokenizer->is(TokenType::COMMA))1105 {1106 $this->tokenizer->readNextToken();1107 continue;1108 }1109 break;1110 }1111 return $retVal;1112 }1113 /**1114 * @throws ParseException1115 * @return \Codemitte\ForceToolkit\Soql\AST\ComparableInterface1116 */1117 private function parsePrimitiveValue()1118 {1119 $retVal = null;1120 if($this->tokenizer->is(TokenType::DATE_LITERAL))1121 {1122 $retVal = new AST\SoqlDate($this->tokenizer->getTokenValue());1123 $this->tokenizer->readNextToken();1124 }1125 elseif($this->tokenizer->is(TokenType::DATETIME_LITERAL))1126 {1127 $retVal = new AST\SoqlDateTime($this->tokenizer->getTokenValue());1128 $this->tokenizer->readNextToken();1129 }1130 // SIGNED NUMBERS1131 elseif($this->tokenizer->is(TokenType::SIGN))1132 {1133 $sign = $this->tokenizer->getTokenValue();1134 $this->tokenizer->readNextToken();1135 $retVal = new AST\SoqlNumber($sign . $this->tokenizer->getTokenValue());1136 $this->tokenizer->expect(TokenType::NUMBER);1137 }1138 // UNSIGNED NUMBERS1139 elseif($this->tokenizer->is(TokenType::NUMBER))1140 {1141 $retVal = new AST\SoqlNumber($this->tokenizer->getTokenValue());1142 $this->tokenizer->readNextToken();1143 }1144 elseif($this->tokenizer->is(TokenType::STRING_LITERAL))1145 {1146 $retVal = new AST\SoqlString($this->tokenizer->getTokenValue());1147 $this->tokenizer->readNextToken();1148 }1149 // DATE FORMULA OR DATE CONSTANT OR CURRENCY SYMBOL?1150 elseif($this->tokenizer->is(TokenType::EXPRESSION))1151 {1152 $val = $this->tokenizer->getTokenValue();1153 $line = $this->tokenizer->getLine();1154 $col = $this->tokenizer->getLinePos();1155 $input = $this->tokenizer->getInput();1156 $uppervaseVal = strtoupper($this->tokenizer->getTokenValue());1157 if(self::BOOL_TRUE === $uppervaseVal)1158 {1159 $retVal = new AST\SoqlTrue();1160 $this->tokenizer->readNextToken();1161 }1162 elseif(self::BOOL_FALSE === $uppervaseVal)1163 {1164 $retVal = new AST\SoqlFalse();1165 $this->tokenizer->readNextToken();1166 }1167 elseif(self::NIL === $uppervaseVal)1168 {1169 $retVal = new AST\SoqlNull();1170 $this->tokenizer->readNextToken();1171 }1172 elseif(in_array($this->tokenizer->getTokenValue(), self::$DATE_CONSTANTS))1173 {1174 $retVal = new AST\SoqlDateLiteral($this->tokenizer->getTokenValue());1175 // ADVANCE ...1176 $this->tokenizer->readNextToken();1177 }1178 elseif(in_array($this->tokenizer->getTokenValue(), self::$DATE_FORMULAS))1179 {1180 $retVal = $this->parseDateFormula();1181 }1182 // CURRENCY, LIKE USD50001183 elseif(preg_match('#^[A-Z]{3}\d+?(?:\\.\d+?)?$#', $this->tokenizer->getTokenValue(), $result))1184 {1185 $retVal = new AST\SoqlCurrencyLiteral($result[0]);1186 }1187 else1188 {1189 throw new ParseException(sprintf('Unexpected expression "%s"', $val), $line, $col, $input);1190 // ONLY USED IN WITH DATA CATEGORY [...] CLAUSE AS RIGHT OPERAND [...]1191 $retVal = new AST\SoqlExpression($val);1192 }1193 }1194 else1195 {1196 throw new ParseException(sprintf('Unexpected token "%s" with value "%s"', $this->tokenizer->getTokenType(), $this->tokenizer->getTokenValue()), $this->tokenizer->getLine(), $this->tokenizer->getLinePos(), $this->tokenizer->getInput());1197 }1198 return $retVal;1199 }1200 /**1201 * @return AST\SoqlDateLiteral1202 */1203 private function parseDateFormula()1204 {1205 $val = $this->tokenizer->getTokenValue();1206 $this->tokenizer->readNextToken();1207 $val .= ':';1208 // ADVANCE ...1209 $this->tokenizer->expect(TokenType::COLON);1210 if(1211 $this->tokenizer->is(TokenType::EXPRESSION) ||1212 $this->tokenizer->is(TokenType::NUMBER)1213 ){1214 $val .= $this->tokenizer->getTokenValue();1215 // ADVANCE ...1216 $this->tokenizer->readNextToken();1217 }1218 else1219 {1220 // THROWS ERROR1221 $this->tokenizer->expect(TokenType::NUMBER);1222 }1223 return new AST\SoqlDateLiteral($val);1224 }1225 /**1226 *1227 * @param string $funcname1228 * @param int $context1229 * @throws ParseException1230 * @return Functions\SoqlFunctionInterface1231 */1232 private function parseFunctionExpression($funcname, $context)1233 {1234 $this->tokenizer->expect(TokenType::LEFT_PAREN);1235 try1236 {1237 $retVal = Functions\Factory::getInstance($funcname, $context, $this->tokenizer, $this->parseFunctionArguments($funcname, $context));1238 }1239 catch(\Exception $e)1240 {1241 throw new ParseException($e->getMessage(), $this->tokenizer->getLine(), $this->tokenizer->getLinePos(), $this->tokenizer->getTokenValue(), $e);1242 }1243 $this->tokenizer->expect(TokenType::RIGHT_PAREN);1244 return $retVal;1245 }1246 /**1247 * ToParse: "function(" -> [...] <- ")"1248 * Parenthesis have already been filtered.1249 *1250 * @param string $funcName1251 * @param int $context1252 * @return array1253 */1254 private function parseFunctionArguments($funcName, $context)1255 {1256 $args = array();1257 // NO ARGS, RETURN1258 if($this->tokenizer->is(TokenType::RIGHT_PAREN))1259 {1260 return $args;1261 }1262 while(true)1263 {1264 $args[] = $this->parseFunctionArgument($funcName, $context);1265 if($this->tokenizer->is(TokenType::COMMA))1266 {1267 // ADVANCE TO NEXT ARGUMENT, OR CLOSING PARENTHESIS1268 $this->tokenizer->readNextToken();1269 continue;1270 }1271 break;1272 }1273 return $args;1274 }1275 /**1276 * Parses a single function argument. Can be expression or1277 * function by itself.1278 *1279 * @param string $funcName1280 * @param int $context1281 * @throws \Exception1282 * @return Functions\SoqlFunctionInterface|AST\SoqlName1283 */1284 private function parseFunctionArgument($funcName, $context)1285 {1286 try1287 {1288 return $this->parsePrimitiveValue();1289 }1290 catch(\Exception $e)1291 {1292 $name = $this->tokenizer->getTokenValue();1293 if($name)1294 {1295 // ADVANCE1296 $this->tokenizer->readNextToken();1297 // NESTED FUNCTION1298 if($this->tokenizer->is(TokenType::LEFT_PAREN))1299 {1300 return $this->parseFunctionExpression($name, $context);1301 }1302 // ARBITRARY IDENTIFIER, e.g. SOQL NAME1303 return new AST\SoqlName($name);1304 }1305 throw $e;1306 }1307 }1308 /**1309 * @return GroupPart1310 */1311 private function parseGroup()1312 {1313 $this->tokenizer->expectKeyword('group');1314 $this->tokenizer->expectKeyword('by');1315 $retVal = new AST\GroupByExpression();1316 if($this->tokenizer->isKeyword('ROLLUP'))1317 {1318 $retVal->setIsRollup();1319 $this->tokenizer->readNextToken();1320 $this->tokenizer->expect(TokenType::LEFT_PAREN);1321 }1322 elseif($this->tokenizer->isKeyword('CUBE'))1323 {1324 $retVal->setIsCube();1325 $this->tokenizer->readNextToken();1326 $this->tokenizer->expect(TokenType::LEFT_PAREN);1327 }1328 $retVal->addGroupFields($this->parseGroupByExpression());1329 // EXPECT LEFT PARANTHESIS IF ROLLUP OR CUBE1330 if($retVal->getIsCube() || $retVal->getIsRollup())1331 {1332 $this->tokenizer->expect(TokenType::RIGHT_PAREN);1333 }1334 return $retVal;1335 }1336 /**1337 * @return array<GroupField>1338 */1339 public function parseGroupByExpression()1340 {1341 $retVal = array();1342 while(true)1343 {1344 $retVal[] = $this->parseGroupByField();1345 try1346 {1347 $this->tokenizer->expect(TokenType::COMMA);1348 }1349 catch(TokenizerException $e)1350 {1351 break;1352 }1353 }1354 return $retVal;1355 }1356 /**1357 * fieldname | AggregateFunction:1358 * AVG(fieldname), COUNT(FIELDNAME), COUNT_DISTINCT(fieldname), MIN(fieldname), MAX(fieldname), SUM(fieldname)1359 * @return \Codemitte\ForceToolkit\Soql\AST\GroupableInterface1360 */1361 private function parseGroupByField()1362 {1363 $retVal = null;1364 $fieldName = $this->tokenizer->getTokenValue();1365 // ADVANCE1366 $this->tokenizer->expect(TokenType::EXPRESSION);1367 // IS (AGGREGATE?) FUNCTION?1368 if($this->tokenizer->is(TokenType::LEFT_PAREN))1369 {1370 return new AST\GroupByFunction($this->parseFunctionExpression($fieldName, Functions\SoqlFunctionInterface::CONTEXT_GROUP_BY));1371 }1372 return new AST\GroupByField($fieldName);1373 }1374 /**1375 * @return AST\HavingPart1376 */1377 private function parseHavingConditionExpression()1378 {1379 $this->tokenizer->expectKeyword('having');1380 return new AST\HavingPart($this->parseHavingLogicalGroup());1381 }1382 /**1383 * @return AST\OrderPart1384 */1385 private function parseOrder()1386 {1387 $this->tokenizer->expectKeyword('order');1388 $this->tokenizer->skipWhitespace();1389 $this->tokenizer->expectKeyword('by');1390 $retVal = new AST\OrderPart();1391 $retVal->addOrderFields($this->parseOrderByExpression());1392 return $retVal;1393 }1394 /**1395 * @return array<OrderByField>1396 */1397 private function parseOrderByExpression()1398 {1399 $retVal = array();1400 while(true)1401 {1402 $retVal[] = $this->parseOrderByField();1403 if($this->tokenizer->is(TokenType::COMMA))1404 {1405 $this->tokenizer->readNextToken();1406 continue;1407 }1408 break;1409 }1410 return $retVal;1411 }1412 /**1413 * ORDER BY fieldExpression ASC | DESC ? NULLS FIRST | LAST ?1414 *1415 * @throws ParseException1416 * @return SortableInterface1417 */1418 private function parseOrderByField()1419 {1420 $retVal = null;1421 $fieldName = $this->tokenizer->getTokenValue();1422 $this->tokenizer->expect(TokenType::EXPRESSION);1423 if($this->tokenizer->is(TokenType::LEFT_PAREN))1424 {1425 $retVal = new AST\OrderByFunction($this->parseFunctionExpression($fieldName, Functions\SoqlFunctionInterface::CONTEXT_ORDER_BY));1426 }1427 else1428 {1429 $retVal = new AST\OrderByField($fieldName);1430 }1431 // ASC/DESC1432 if($this->tokenizer->isKeyword('asc'))1433 {1434 $retVal->setDirection(AST\OrderByField::DIRECTION_ASC);1435 $this->tokenizer->readNextToken();1436 }1437 elseif($this->tokenizer->isKeyword('desc'))1438 {1439 $retVal->setDirection(AST\OrderByField::DIRECTION_DESC);1440 $this->tokenizer->readNextToken();1441 }1442 if($this->tokenizer->isKeyword('NULLS'))1443 {1444 $this->tokenizer->readNextToken();1445 if($this->tokenizer->isKeyword('last'))1446 {1447 $retVal->setNulls(AST\OrderByField::NULLS_LAST);1448 }1449 elseif($this->tokenizer->isKeyword('first'))1450 {1451 $retVal->setNulls(AST\OrderByField::NULLS_FIRST);1452 }1453 else1454 {1455 throw new ParseException(sprintf('Unexpected "%s"', $this->tokenizer->getTokenValue()), $this->tokenizer->getLine(), $this->tokenizer->getLinePos(), $this->tokenizer->getInput());1456 }1457 $this->tokenizer->expect(TokenType::KEYWORD);1458 }1459 return $retVal;1460 }1461 /**1462 * @return int1463 */1464 private function parseLimit()1465 {1466 $this->tokenizer->expectKeyword('limit');1467 $v = $this->tokenizer->getTokenValue();1468 $this->tokenizer->expect(TokenType::NUMBER);1469 return $v;1470 }1471 /**1472 * @return int1473 */1474 private function parseOffset()1475 {1476 $this->tokenizer->expectKeyword('offset');1477 $v = $this->tokenizer->getTokenValue();1478 $this->tokenizer->expect(TokenType::NUMBER);1479 return $v;1480 }1481 /**1482 * getNamedParameter()1483 *1484 * @throws ParseException1485 *1486 * @return AST\NamedVariable1487 */1488 private function parseNamedVariable()1489 {1490 $this->tokenizer->expect(TokenType::COLON);1491 $name = $this->tokenizer->getTokenValue();1492 $retVal = new AST\NamedVariable($name);1493 $this->tokenizer->expect(TokenType::EXPRESSION);1494 return $retVal;1495 }1496 /**1497 * getIndexedParameter()1498 *1499 * @throws ParseException1500 *1501 * @return AST\AnonymousVariable1502 */1503 private function parseAnonVariable()1504 {1505 $this->tokenizer->expect(TokenType::ANON_VARIABLE);1506 return new AST\AnonymousVariable($this->varIndex);1507 }1508 /**1509 * TYPEOF special select syntax.1510 * SELECT [...] TYPEOF fieldname WHEN type1 THEN fieldlist1 [WHEN type2 THEN fieldlist 2] [ELSE elsefieldlist] END1511 * - SELECT TYPEOF [...] is only valid in outer SELECT clause1512 * - NO GROUP BY [ROLLUP|CUBE] AND HAVING ALLOWED1513 *1514 * @return \Codemitte\ForceToolkit\Soql\AST\TypeofSelectPart1515 */1516 private function parseSelectTypeofExpression()1517 {1518 // SOBJECT NAME1519 $sobjectName = $this->tokenizer->getTokenValue();1520 $this->tokenizer->readNextToken();1521 // AT LEAST ONE "WHEN" keyword1522 $this->tokenizer->expectKeyword('when');1523 // CONDITION1524 $sobjectFieldname = $this->tokenizer->getTokenValue();1525 $this->tokenizer->expect(TokenType::EXPRESSION);1526 $this->tokenizer->expectKeyword('then');1527 // THEN ...1528 $fieldlist = $this->parseTypeofSelectFields();1529 $typeofSelectPart = new AST\TypeofSelectPart();1530 $typeofSelectPart->setSobjectName($sobjectName);1531 $typeofSelectPart->addCondition(new AST\TypeofCondition($sobjectFieldname, new AST\SelectPart($fieldlist)));1532 while(true)1533 {1534 if($this->tokenizer->isKeyword('when'))1535 {1536 $this->tokenizer->readNextToken();1537 // EXPRESSION AND/OR KEYWORD ("GROUP")1538 $sobjectFieldname = $this->tokenizer->getTokenValue();1539 $this->tokenizer->readNextToken();1540 $this->tokenizer->expectKeyword('then');1541 $fieldlist = $this->parseTypeofSelectFields();1542 $typeofSelectPart->setSobjectName($sobjectName);1543 $typeofSelectPart->addCondition(new AST\TypeofCondition($sobjectFieldname, new AST\SelectPart($fieldlist)));1544 continue;1545 }1546 elseif($this->tokenizer->isKeyword('else'))1547 {1548 $this->tokenizer->readNextToken();1549 $fieldlist = $this->parseTypeofSelectFields();1550 $typeofSelectPart->setElse(new AST\SelectPart($fieldlist));1551 }1552 break; // ELSE IS THE END OF THE FAHNENSTANGE1553 }1554 return $typeofSelectPart;1555 }1556 /**1557 * @return array<AST\TypeofSelectField>1558 */1559 private function parseTypeofSelectFields()1560 {1561 $selectFields = array();1562 /* (SELECT, FUNCTION() [alias], fieldname [alias])1563 SELECT COUNT() special case1564 SELECT [...] TYPEOF fieldname WHEN type1 THEN fieldlist1 [WHEN type2 THEN fieldlist 2] [ELSE elsefieldlist] END1565 - SELECT TYPEOF [...] is only valid in outer SELECT clause1566 - NO GROUP BY [ROLLUP|CUBE] AND HAVING ALLOWED1567 */1568 while(true)1569 {1570 $selectFields[] = $this->parseTypeofSelectField();1571 if($this->tokenizer->is(TokenType::COMMA))1572 {1573 $this->tokenizer->readNextToken();1574 continue;1575 }1576 break;1577 }1578 return $selectFields;1579 }1580 /**1581 *1582 * @throws ParseException1583 * @return AST\SelectFieldInterface1584 */1585 private function parseTypeofSelectField()1586 {1587 $retVal = null;1588 $name = $this->tokenizer->getTokenValue();1589 $this->tokenizer->readNextToken();1590 // REGULAR OR AGGREGATE FUNCTION1591 if($this->tokenizer->is(TokenType::LEFT_PAREN))1592 {1593 $retVal = new AST\SelectFunction($this->parseFunctionExpression($name, Functions\SoqlFunctionInterface::CONTEXT_SELECT));1594 }1595 // PLAIN FIELDNAME1596 else1597 {1598 $retVal = new AST\SelectField($name);1599 }1600 // ALIAS1601 if($this->tokenizer->is(TokenType::EXPRESSION) && $retVal instanceof AST\CanHazAliasInterface)1602 {...
CsrfTest.php
Source:CsrfTest.php
...41 public function testTokenKeys()42 {43 $mw = new Guard('test');44 $this->assertEquals('test_name', $mw->getTokenNameKey());45 $this->assertEquals('test_value', $mw->getTokenValueKey());46 }47 public function testTokenGeneration()48 {49 $storage = [];50 $request = $this->request;51 $response = $this->response;52 $mw = new Guard('csrf', $storage);53 $next = function ($req, $res) use ($mw) {54 return $res55 ->withHeader('X-CSRF-NAME', $req->getAttribute($mw->getTokenNameKey()))56 ->withHeader('X-CSRF-VALUE', $req->getAttribute($mw->getTokenValueKey()));57 };58 $response1 = $mw($request, $response, $next);59 $response2 = $mw($request, $response, $next);60 61 $this->assertStringStartsWith('csrf', $response1->getHeaderLine('X-CSRF-NAME'), 'Name key should start with csrf prefix');62 $this->assertStringStartsWith('csrf', $response2->getHeaderLine('X-CSRF-NAME'), 'Name key should start with csrf prefix');63 64 $this->assertNotEquals($response1->getHeaderLine('X-CSRF-NAME'), $response2->getHeaderLine('X-CSRF-NAME'), 'Generated token names must be unique');65 66 $this->assertEquals(32, strlen($response1->getHeaderLine('X-CSRF-VALUE')), 'Length of the generated token value should be double the strength');67 $this->assertEquals(32, strlen($response2->getHeaderLine('X-CSRF-VALUE')), 'Length of the generated token value should be double the strength');68 69 $this->assertTrue(ctype_xdigit($response1->getHeaderLine('X-CSRF-VALUE')), 'Generated token value is not hexadecimal');70 $this->assertTrue(ctype_xdigit($response2->getHeaderLine('X-CSRF-VALUE')), 'Generated token value is not hexadecimal');71 }72 public function testValidToken()73 {74 $storage = ['csrf_123' => 'xyz'];75 $request = $this->request76 ->withMethod('POST')77 ->withParsedBody([78 'csrf_name' => 'csrf_123',79 'csrf_value' => 'xyz'80 ]);81 $response = $this->response;82 $next = function ($req, $res) {83 return $res;84 };85 $mw = new Guard('csrf', $storage);86 $newResponse = $mw($request, $response, $next);87 $this->assertEquals(200, $newResponse->getStatusCode());88 }89 public function testInvalidToken()90 {91 $storage = ['csrf_123' => 'abc']; // <-- Invalid token value92 $request = $this->request93 ->withMethod('POST')94 ->withParsedBody([95 'csrf_name' => 'csrf_123',96 'csrf_value' => 'xyz'97 ]);98 $response = $this->response;99 $next = function ($req, $res) {100 return $res;101 };102 $mw = new Guard('csrf', $storage);103 $newResponse = $mw($request, $response, $next);104 $this->assertEquals(400, $newResponse->getStatusCode());105 }106 public function testMissingToken()107 {108 $storage = []; // <-- Missing token name and value109 $request = $this->request110 ->withMethod('POST')111 ->withParsedBody([112 'csrf_name' => 'csrf_123',113 'csrf_value' => 'xyz'114 ]);115 $response = $this->response;116 $next = function ($req, $res) {117 return $res;118 };119 $mw = new Guard('csrf', $storage);120 $newResponse = $mw($request, $response, $next);121 $this->assertEquals(400, $newResponse->getStatusCode());122 }123 public function testExternalStorageOfAnArrayAccessPersists()124 {125 $storage = new \ArrayObject();126 127 $request = $this->request128 ->withMethod('POST')129 ->withParsedBody([130 'csrf_name' => 'csrf_123',131 'csrf_value' => 'xyz'132 ]);133 $response = $this->response;134 $next = function ($req, $res) {135 return $res;136 };137 $mw = new Guard('csrf', $storage);138 $this->assertEquals(0, count($storage));139 $newResponse = $mw($request, $response, $next);140 $this->assertEquals(1, count($storage));141 }142 public function testExternalStorageOfAnArrayPersists()143 {144 $storage = [];145 146 $request = $this->request147 ->withMethod('POST')148 ->withParsedBody([149 'csrf_name' => 'csrf_123',150 'csrf_value' => 'xyz'151 ]);152 $response = $this->response;153 $next = function ($req, $res) {154 return $res;155 };156 $mw = new Guard('csrf', $storage);157 $this->assertEquals(0, count($storage));158 $newResponse = $mw($request, $response, $next);159 $this->assertEquals(1, count($storage));160 }161 public function testPersistenceModeTrueBetweenRequestsArray()162 {163 $storage = [];164 $mw = new Guard('csrf', $storage, null, 200, 16, true);165 $next = function ($req, $res) {166 return $res;167 };168 // Token name and value should be null if the storage is empty and middleware has not yet been invoked169 $this->assertNull($mw->getTokenName());170 $this->assertNull($mw->getTokenValue()); 171 172 $response = $mw($this->request, $this->response, $next);173 // Persistent token name and value have now been generated174 $name = $mw->getTokenName();175 $value = $mw->getTokenValue(); 176 // Subsequent request will attempt to validate the token177 $request = $this->request178 ->withMethod('POST')179 ->withParsedBody([180 'csrf_name' => $name,181 'csrf_value' => $value182 ]);183 $response = $mw($request, $this->response, $next);184 // Token name and value should be the same after subsequent request185 $this->assertEquals($name, $mw->getTokenName());186 $this->assertEquals($value, $mw->getTokenValue());187 }188 189 public function testPersistenceModeTrueBetweenRequestsArrayAccess()190 {191 $storage = new \ArrayObject();192 $mw = new Guard('csrf', $storage, null, 200, 16, true);193 $next = function ($req, $res) {194 return $res;195 };196 // Token name and value should be null if the storage is empty and middleware has not yet been invoked197 $this->assertNull($mw->getTokenName());198 $this->assertNull($mw->getTokenValue()); 199 200 $response = $mw($this->request, $this->response, $next);201 // Persistent token name and value have now been generated202 $name = $mw->getTokenName();203 $value = $mw->getTokenValue(); 204 // Subsequent request will attempt to validate the token205 $request = $this->request206 ->withMethod('POST')207 ->withParsedBody([208 'csrf_name' => $name,209 'csrf_value' => $value210 ]);211 $response = $mw($request, $this->response, $next);212 213 // Token name and value should be the same after subsequent request214 $this->assertEquals($name, $mw->getTokenName());215 $this->assertEquals($value, $mw->getTokenValue());216 } 217 218 public function testPersistenceModeFalseBetweenRequestsArray()219 {220 $storage = [];221 $mw = new Guard('csrf', $storage);222 $next = function ($req, $res) {223 return $res;224 };225 // Token name and value should be null if the storage is empty and middleware has not yet been invoked226 $this->assertNull($mw->getTokenName());227 $this->assertNull($mw->getTokenValue()); 228 229 $response = $mw($this->request, $this->response, $next);230 // First token name and value have now been generated231 $name = $mw->getTokenName();232 $value = $mw->getTokenValue(); 233 // Subsequent request will attempt to validate the token234 $request = $this->request235 ->withMethod('POST')236 ->withParsedBody([237 'csrf_name' => $name,238 'csrf_value' => $value239 ]);240 $response = $mw($request, $this->response, $next);241 // Token name and value should NOT be the same after subsequent request242 $this->assertNotEquals($name, $mw->getTokenName());243 $this->assertNotEquals($value, $mw->getTokenValue());244 }245 246 public function testPersistenceModeFalseBetweenRequestsArrayAccess()247 {248 $storage = new \ArrayObject();249 $mw = new Guard('csrf', $storage);250 $next = function ($req, $res) {251 return $res;252 };253 // Token name and value should be null if the storage is empty and middleware has not yet been invoked254 $this->assertNull($mw->getTokenName());255 $this->assertNull($mw->getTokenValue()); 256 257 $response = $mw($this->request, $this->response, $next);258 // First token name and value have now been generated259 $name = $mw->getTokenName();260 $value = $mw->getTokenValue(); 261 // Subsequent request will attempt to validate the token262 $request = $this->request263 ->withMethod('POST')264 ->withParsedBody([265 'csrf_name' => $name,266 'csrf_value' => $value267 ]);268 $response = $mw($request, $this->response, $next);269 // Token name and value should NOT be the same after subsequent request270 $this->assertNotEquals($name, $mw->getTokenName());271 $this->assertNotEquals($value, $mw->getTokenValue());272 }273 274 public function testUpdateAfterInvalidTokenWithPersistenceModeTrue()275 {276 $storage = [];277 $mw = new Guard('csrf', $storage, null, 200, 16, true);278 $next = function ($req, $res) {279 return $res;280 };281 $response = $mw($this->request, $this->response, $next);282 // Persistent token name and value have now been generated283 $name = $mw->getTokenName();284 $value = $mw->getTokenValue();285 // Bad request, token should get updated286 $request = $this->request287 ->withMethod('POST')288 ->withParsedBody([289 'csrf_name' => 'csrf_123',290 'csrf_value' => 'xyz'291 ]); 292 $response = $mw($request, $this->response, $next);293 // Token name and value should NOT be the same after subsequent request294 $this->assertNotEquals($name, $mw->getTokenName());295 $this->assertNotEquals($value, $mw->getTokenValue());296 } 297 298 public function testStorageLimitIsEnforcedForObjects()299 {300 $storage = new \ArrayObject();301 302 $request = $this->request;303 $response = $this->response;304 $next = function ($req, $res) {305 return $res;306 };307 $mw = new Guard('csrf', $storage);308 $mw->setStorageLimit(2);309 $this->assertEquals(0, count($storage));310 $response = $mw($request, $response, $next);311 $response = $mw($request, $response, $next);312 $response = $mw($request, $response, $next);313 $this->assertEquals(2, count($storage));314 }315 public function testStorageLimitIsEnforcedForArrays()316 {317 $storage = [];318 319 $request = $this->request;320 $response = $this->response;321 $next = function ($req, $res) {322 return $res;323 };324 $mw = new Guard('csrf', $storage);325 $mw->setStorageLimit(2);326 $this->assertEquals(0, count($storage));327 $response = $mw($request, $response, $next);328 $response = $mw($request, $response, $next);329 $response = $mw($request, $response, $next);330 $this->assertEquals(2, count($storage));331 }332 public function testKeyPair() {333 $mw = new Guard();334 $next = function ($req, $res) {335 return $res;336 };337 $response = $mw($this->request, $this->response, $next);338 $this->assertNotNull($mw->getTokenName());339 $this->assertNotNull($mw->getTokenValue());340 }341 public function testDefaultStorageIsSession()342 {343 $sessionBackup = $_SESSION;344 $_SESSION = array();345 $mw = new Guard('csrf');346 $mw->validateStorage();347 $this->assertNotEmpty($_SESSION);348 $_SESSION = $sessionBackup;349 }350}...
ViewFieldUnitTest.php
Source:ViewFieldUnitTest.php
...70 $this->assertEquals($result, $expected, 'The token string has been split correctly (",").');71 $result = $field_handler->splitTokens('{{ raw_fields.uid }}/{{ fields.nid }}');72 $this->assertEquals($result, $expected, 'The token string has been split correctly ("/").');73 // Test the get_token_argument() method.74 $result = $field_handler->getTokenValue('{{ raw_fields.id }}', $view->result[0], $view);75 $this->assertEquals(2, $result);76 $result = $field_handler->getTokenValue('{{ fields.id }}', $view->result[0], $view);77 $this->assertEquals(3, $result);78 $result = $field_handler->getTokenValue('{{ raw_fields.id_1 }}', $view->result[0], $view);79 $this->assertEquals(2, $result);80 $result = $field_handler->getTokenValue('{{ fields.id_1 }}', $view->result[0], $view);81 $this->assertEquals(3, $result);82 $result = $field_handler->getTokenValue('{{ raw_fields.name }}', $view->result[0], $view);83 $this->assertEquals('George', $result);84 $result = $field_handler->getTokenValue('{{ fields.name }}', $view->result[0], $view);85 $this->assertEquals('Ringo', $result);86 $result = $field_handler->getTokenValue('{{ raw_arguments.null }}', $view->result[0], $view);87 $this->assertEquals('Hey jude', $result);88 $result = $field_handler->getTokenValue('{{ arguments.null }}', $view->result[0], $view);89 $this->assertEquals('Hey jude', $result);90 }91}...
UserController.php
Source:UserController.php
...25 public function actionIsLogin()26 {27 if ($_COOKIE[Constant::$REMEMBER_TOKEN]) {28 $token = $_COOKIE[Constant::$REMEMBER_TOKEN];29 $user = Token::getTokenValue($token);30 if ($user) {31 return $user;32 }33 }34 return ['code' => "0", 'msg' => "user not login"];35 }3637 public function actionLogin()38 {39 $loginModel = Yii::$app->request->post();4041 if ($loginModel) {42 $username = $loginModel['username'];43 $password = $loginModel['password'];44 $rememberMe = $loginModel['rememberMe'];45 return User::login($username, $password, $rememberMe);46 }47 return ['code' => "200", 'msg' => "login success"];48 }4950 public function actionLogout()51 {52 if (isset($_COOKIE[Constant::$SESSION_TOKEN])) {53 $token = $_COOKIE[Constant::$SESSION_TOKEN];54 if (Token::getTokenValue($token)) {55 Yii::$app->redis->del($token);56 unset($_COOKIE[Constant::$SESSION_TOKEN]);57 }58 }59 if (isset($_COOKIE[Constant::$REMEMBER_TOKEN])) {60 $token = $_COOKIE[Constant::$REMEMBER_TOKEN];61 if (Token::getTokenValue($token)) {62 Yii::$app->redis->del($token);63 unset($_COOKIE[Constant::$REMEMBER_TOKEN]);64 }65 }66 }6768 public function actionRegister()69 {70 $registerModel = Yii::$app->request->post();7172 if ($registerModel) {73 $username = $registerModel['username'];74 $password = $registerModel['password'];75 if (User::findByUsername($username) != null) {76 return ['code' => "0", 'msg' => "The user name already exists"];77 } else {78 return User::register($username, $password);79 }80 }81 return ['code' => "-1", 'msg' => "Incorrect user name or password input format"];8283 }8485 public function actionChangepassword()86 {87 $model = Yii::$app->request->post();88 $oldPassword = $model['oldPassword'];89 $password = $model['password'];90 $token = $_COOKIE[Constant::$SESSION_TOKEN];91 $user = Token::getTokenValue($token);9293 if ($model) {94 if ($user && md5($oldPassword) == $user->password) {95 return User::changePassword($user->id, $password);96 }97 return ['code' => "0", 'msg' => "old password is incorrect"];98 }99 }100101 public function actionIsResport()102 {103 if ($_COOKIE[Constant::$SESSION_TOKEN]) {104 $token = $_COOKIE[Constant::$SESSION_TOKEN];105 $user = Token::getTokenValue($token);106 if ($user->permission == "1") {107 return ['code' => "0", 'msg' => "user has permission"];108 }109 }110111 return ['code' => "1", 'msg' => "user has not permission"];112 }113}
...
ParserTest.php
Source:ParserTest.php
...45 46 public function testParseSimpleTemplate()47 {48 $data = "This is a %%%TOKEN%%%";49 $this->_provider->expects($this->at(0))->method('getTokenValue')->with('TOKEN')50 ->will($this->returnValue("TOKENVALUE"));51 $str = $this->_parser->parse($data);52 $this->assertEquals("This is a TOKENVALUE", $str);53 }54 55 public function testLongerTemplate()56 {57 $data = "This is a <b>really</b> long template with %%%TOKEN1%%% a couple of different58 tokens and it does lots of stuff. The second token is %%%TOKEN2%%% and then we can59 go back to the first one with %%%TOKEN1%%% and thesecond one will be %%%TOKEN2%%% and I60 really like pizza and token 3 is %%%TOKEN3%%%. We also <span class='ono'>hope</span> that % signs won't break61 things incase someone puts 100% in there or something.";62 $this->_parser->setTemplateData($data);63 $this->_provider->expects($this->at(0))->method('getTokenValue')64 ->with('TOKEN1')->will($this->returnValue('TOKEN1VALUE'));65 $this->_provider->expects($this->at(1))->method('getTokenValue')66 ->with('TOKEN2')->will($this->returnValue('TOKEN2VALUE'));67 $this->_provider->expects($this->at(2))->method('getTokenValue')68 ->with('TOKEN1')->will($this->returnValue('TOKEN1VALUE'));69 $this->_provider->expects($this->at(3))->method('getTokenValue')70 ->with('TOKEN2')->will($this->returnValue('TOKEN2VALUE'));71 $this->_provider->expects($this->at(4))->method('getTokenValue')72 ->with('TOKEN3')->will($this->returnValue('TOKEN3VALUE'));73 $expected = str_replace(74 array('%%%TOKEN1%%%', '%%%TOKEN2%%%', '%%%TOKEN3%%%'),75 array('TOKEN1VALUE', 'TOKEN2VALUE', 'TOKEN3VALUE'),76 $data77 );78 $this->assertEquals($expected, $this->_parser->parse());79 }80 81}...
StringTokenScannerTest.php
Source:StringTokenScannerTest.php
...15 {16 $contents = "FOO\nBAR\r\nBAZ\n";17 $scanner = new StringTokenScanner($contents);18 $token = $scanner->read();19 self::assertSame('FOO', $token->getTokenValue());20 $token = $scanner->read();21 self::assertSame('BAR', $token->getTokenValue());22 $token = $scanner->read();23 self::assertSame('BAZ', $token->getTokenValue());24 $token = $scanner->read();25 self::assertSame('EOF', $token->getTokenValue());26 self::assertTrue($token->isEof());27 }28 public function testItFindsEmptyLines(): void29 {30 $contents = "FOO\n\nBAR\n";31 $scanner = new StringTokenScanner($contents);32 $token = $scanner->read();33 self::assertSame('FOO', $token->getTokenValue());34 $token = $scanner->read();35 self::assertSame('', $token->getTokenValue());36 $token = $scanner->read();37 self::assertSame('BAR', $token->getTokenValue());38 $token = $scanner->read();39 self::assertSame('EOF', $token->getTokenValue());40 self::assertTrue($token->isEof());41 }42}...
SpanDecoratorTest.php
Source:SpanDecoratorTest.php
...3{4 public function testSingleToken()5 {6 $provider = $this->getMock('Template_ITokenProvider');7 $provider->expects($this->once())->method('getTokenValue')8 ->with('token')->will($this->returnValue('value'));9 $decorator = new Template_SpanDecorator($provider);10 $this->assertEquals("<span class=\"token token1\">value</span>", $decorator->getTokenValue('token')); 11 }12 13 public function testMultipleTokens()14 {15 $tokens = array('token1', 'token2', 'token1');16 $provider = $this->getMock('Template_ITokenProvider');17 $provider->expects($this->at(0))->method('getTokenValue')18 ->with('token1')->will($this->returnValue('value1'));19 $provider->expects($this->at(1))->method('getTokenValue')20 ->with('token2')->will($this->returnValue('value2'));21 $provider->expects($this->at(2))->method('getTokenValue')22 ->with('token1')->will($this->returnValue('value1'));23 $decorator = new Template_SpanDecorator($provider);24 $this->assertEquals("<span class=\"token1 token11\">value1</span>", $decorator->getTokenValue('token1'));25 $this->assertEquals("<span class=\"token2 token21\">value2</span>", $decorator->getTokenValue('token2'));26 $this->assertEquals("<span class=\"token1 token12\">value1</span>", $decorator->getTokenValue('token1')); 27 }28}...
service-two-protected.php
Source:service-two-protected.php
2use Ling\CSRFTools\CSRFProtector;3require_once __DIR__ . "/../setup.php";4$tokenName = "token-s2";5if (array_key_exists($tokenName, $_GET)) {6 $getTokenValue = $_GET[$tokenName];7 if (true === CSRFProtector::inst()->isValid($tokenName, $getTokenValue, true)) {8 success_message_service('two', $getTokenValue);9 } else {10 error_message("The given csrf token is not valid ($getTokenValue).");11 }12} else {13 error_message("Access to service two denied.");14}
getTokenValue
Using AI Code Generation
1require_once 'Token.php';2$token = new Token();3$tokenValue = $token->getTokenValue();4echo $tokenValue;5require_once 'Token.php';6$token = new Token();7$token->validateToken();
getTokenValue
Using AI Code Generation
1$token = new Token();2echo $token->getTokenValue();3$token = new Token();4if($token->checkTokenValue($token_value)){5 echo 'Token value matched';6}else{7 echo 'Token value not matched';8}
getTokenValue
Using AI Code Generation
1require_once('Token.php');2$token = new Token();3echo $token->getTokenValue();4require_once('Token.php');5$token = new Token();6echo $token->validateTokenValue();7require_once('Token.php');8$token = new Token();9echo $token->validateTokenValue();10require_once('Token.php');11$token = new Token();12echo $token->validateTokenValue();13require_once('Token.php');14$token = new Token();15echo $token->validateTokenValue();16require_once('Token.php');17$token = new Token();18echo $token->validateTokenValue();19require_once('Token.php');20$token = new Token();21echo $token->validateTokenValue();
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Execute automation tests with getTokenValue on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.
Test now for FreeGet 100 minutes of automation test minutes FREE!!