├── .github ├── actions │ └── tag_bump │ │ ├── Dockerfile │ │ ├── action.yml │ │ └── entrypoint.sh └── workflows │ ├── check_sem_ver.yml │ ├── ci.yml │ ├── tag_latest.yml │ └── tests.yml ├── .gitignore ├── .scrutinizer.yml ├── .travis.yml ├── CHANGELOG.md ├── CHANGES.md ├── CONTRIBUTING.md ├── Docs ├── OData PHP Producer Library User Guide.htm ├── OData PHP Producer Library User Guide.pdf └── OData PHP Producer Library User Guide_files │ ├── colorschememapping.xml │ ├── filelist.xml │ ├── header.htm │ ├── image001.png │ ├── image002.jpg │ ├── image003.png │ ├── image004.jpg │ ├── image005.png │ ├── image006.jpg │ ├── image007.png │ ├── image008.png │ ├── image009.jpg │ ├── image010.png │ ├── image011.png │ ├── image012.png │ ├── image013.jpg │ ├── image014.png │ ├── image015.png │ ├── image016.png │ ├── image017.png │ ├── image018.jpg │ ├── image019.jpg │ ├── image020.jpg │ ├── image021.jpg │ ├── image022.png │ ├── image023.jpg │ ├── image024.png │ ├── image025.png │ ├── image026.jpg │ ├── image027.png │ ├── image028.png │ ├── image029.png │ ├── image030.jpg │ ├── image031.png │ ├── image032.jpg │ ├── image033.png │ ├── image034.jpg │ ├── image035.png │ ├── image036.jpg │ ├── image037.jpg │ ├── image038.jpg │ ├── item0001.xml │ ├── props002.xml │ └── themedata.thmx ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml.dist ├── src └── POData │ ├── BaseService.php │ ├── BatchProcessor │ ├── BatchProcessor.php │ ├── ChangeSetParser.php │ ├── IBatchParser.php │ ├── IncomingChangeSetRequest.php │ └── QueryParser.php │ ├── Common │ ├── ErrorHandler.php │ ├── HttpHeaderFailure.php │ ├── HttpStatus.php │ ├── InvalidOperationException.php │ ├── Messages.php │ ├── Messages │ │ ├── IService.php │ │ ├── common.php │ │ ├── configuration.php │ │ ├── eTag.php │ │ ├── expandProjectionParser.php │ │ ├── expressionLexer.php │ │ ├── expressionParser.php │ │ ├── http.php │ │ ├── httpProcessUtility.php │ │ ├── keyDescriptor.php │ │ ├── metadataAssociationType.php │ │ ├── metadataResourceType.php │ │ ├── metadataWriter.php │ │ ├── navigation.php │ │ ├── objectModelSerializer.php │ │ ├── orderByInfo.php │ │ ├── providersWrapper.php │ │ ├── queryProcessor.php │ │ ├── queryProvider.php │ │ ├── request.php │ │ ├── resourceAssociationSet.php │ │ ├── resourceAssociationType.php │ │ ├── resourceProperty.php │ │ ├── resourceSet.php │ │ ├── resourceType.php │ │ ├── responseWriter.php │ │ ├── segmentParser.php │ │ ├── skipTokenInfo.php │ │ ├── skipTokenParser.php │ │ ├── streamProviderWrapper.php │ │ └── uriProcessor.php │ ├── MimeTypes.php │ ├── NotImplementedException.php │ ├── ODataConstants.php │ ├── ODataException.php │ ├── ReflectionHandler.php │ ├── Url.php │ ├── UrlFormatException.php │ └── Version.php │ ├── Configuration │ ├── EntitySetRights.php │ ├── IServiceConfiguration.php │ ├── ProtocolVersion.php │ └── ServiceConfiguration.php │ ├── HttpProcessUtility.php │ ├── IRequestHandler.php │ ├── IService.php │ ├── MediaType.php │ ├── ObjectModel │ ├── AtomObjectModel │ │ ├── AtomAuthor.php │ │ └── AtomContent.php │ ├── CynicDeserialiser.php │ ├── CynicSerialiser.php │ ├── IOData.php │ ├── IObjectSerialiser.php │ ├── ModelDeserialiser.php │ ├── ODataBagContent.php │ ├── ODataCategory.php │ ├── ODataContainerBase.php │ ├── ODataEntry.php │ ├── ODataExpandedResult.php │ ├── ODataFeed.php │ ├── ODataLink.php │ ├── ODataMediaLink.php │ ├── ODataNextPageLink.php │ ├── ODataProperty.php │ ├── ODataPropertyContent.php │ ├── ODataTitle.php │ ├── ODataURL.php │ ├── ODataURLCollection.php │ ├── ObjectModelSerializer.php │ └── XMLAttribute.php │ ├── OperationContext │ ├── HTTPRequestMethod.php │ ├── IHTTPRequest.php │ ├── IOperationContext.php │ ├── ServiceHost.php │ ├── SimpleOperativeContext.php │ ├── SimpleRequestAdapter.php │ └── Web │ │ ├── IncomingRequest.php │ │ ├── OutgoingResponse.php │ │ └── WebOperationContext.php │ ├── Pluralizer.php │ ├── Providers │ ├── Expression │ │ ├── IExpressionProvider.php │ │ ├── MySQLExpressionProvider.php │ │ └── PHPExpressionProvider.php │ ├── Metadata │ │ ├── EdmSchemaVersion.php │ │ ├── IMetadataProvider.php │ │ ├── ResourceAssociationSet.php │ │ ├── ResourceAssociationSetEnd.php │ │ ├── ResourceAssociationType.php │ │ ├── ResourceAssociationTypeEnd.php │ │ ├── ResourceComplexType.php │ │ ├── ResourceEntityType.php │ │ ├── ResourceFunctionType.php │ │ ├── ResourcePrimitiveType.php │ │ ├── ResourceProperty.php │ │ ├── ResourcePropertyKind.php │ │ ├── ResourceSet.php │ │ ├── ResourceSetWrapper.php │ │ ├── ResourceStreamInfo.php │ │ ├── ResourceType.php │ │ ├── ResourceTypeKind.php │ │ ├── SimpleMetadataProvider.php │ │ └── Type │ │ │ ├── Binary.php │ │ │ ├── Boolean.php │ │ │ ├── Byte.php │ │ │ ├── Char.php │ │ │ ├── DateTime.php │ │ │ ├── Decimal.php │ │ │ ├── Double.php │ │ │ ├── EdmPrimitiveType.php │ │ │ ├── EdmString.php │ │ │ ├── Guid.php │ │ │ ├── INavigationType.php │ │ │ ├── IType.php │ │ │ ├── Int16.php │ │ │ ├── Int32.php │ │ │ ├── Int64.php │ │ │ ├── Navigation.php │ │ │ ├── Null1.php │ │ │ ├── SByte.php │ │ │ ├── Single.php │ │ │ ├── StringType.php │ │ │ ├── TypeCode.php │ │ │ └── VoidType.php │ ├── ProvidersQueryWrapper.php │ ├── ProvidersWrapper.php │ ├── Query │ │ ├── IQueryProvider.php │ │ ├── QueryResult.php │ │ └── QueryType.php │ └── Stream │ │ ├── IStreamProvider.php │ │ ├── IStreamProvider2.php │ │ ├── SimpleStreamProvider.php │ │ └── StreamProviderWrapper.php │ ├── Readers │ ├── Atom │ │ ├── AtomODataReader.php │ │ └── Processors │ │ │ ├── BaseNodeHandler.php │ │ │ ├── Entry │ │ │ ├── LinkProcessor.php │ │ │ └── PropertyProcessor.php │ │ │ ├── EntryProcessor.php │ │ │ └── FeedProcessor.php │ ├── IODataReader.php │ └── ODataReaderRegistry.php │ ├── SimpleDataService.php │ ├── UriProcessor │ ├── Interfaces │ │ └── IUriProcessor.php │ ├── QueryProcessor │ │ ├── ExpandProjectionParser │ │ │ ├── ExpandProjectionParser.php │ │ │ ├── ExpandedProjectionNode.php │ │ │ ├── ProjectionNode.php │ │ │ └── RootProjectionNode.php │ │ ├── ExpressionParser │ │ │ ├── ExpressionLexer.php │ │ │ ├── ExpressionParser.php │ │ │ ├── ExpressionParser2.php │ │ │ ├── ExpressionProcessor.php │ │ │ ├── ExpressionToken.php │ │ │ ├── ExpressionTokenId.php │ │ │ ├── Expressions │ │ │ │ ├── AbstractExpression.php │ │ │ │ ├── ArithmeticExpression.php │ │ │ │ ├── BinaryExpression.php │ │ │ │ ├── ConstantExpression.php │ │ │ │ ├── ExpressionType.php │ │ │ │ ├── FunctionCallExpression.php │ │ │ │ ├── LogicalExpression.php │ │ │ │ ├── PropertyAccessExpression.php │ │ │ │ ├── RelationalExpression.php │ │ │ │ └── UnaryExpression.php │ │ │ └── FilterInfo.php │ │ ├── FunctionDescription.php │ │ ├── OrderByParser │ │ │ ├── InternalOrderByInfo.php │ │ │ ├── OrderByBaseNode.php │ │ │ ├── OrderByInfo.php │ │ │ ├── OrderByLeafNode.php │ │ │ ├── OrderByNode.php │ │ │ ├── OrderByParser.php │ │ │ ├── OrderByPathSegment.php │ │ │ ├── OrderByRootNode.php │ │ │ └── OrderBySubPathSegment.php │ │ ├── QueryProcessor.php │ │ └── SkipTokenParser │ │ │ ├── InternalSkipTokenInfo.php │ │ │ ├── SkipTokenInfo.php │ │ │ └── SkipTokenParser.php │ ├── RequestDescription.php │ ├── RequestExpander.php │ ├── ResourcePathProcessor │ │ ├── ResourcePathProcessor.php │ │ └── SegmentParser │ │ │ ├── KeyDescriptor.php │ │ │ ├── SegmentDescriptor.php │ │ │ ├── SegmentParser.php │ │ │ ├── TargetKind.php │ │ │ └── TargetSource.php │ ├── SegmentStack.php │ ├── UriProcessor.php │ └── UriProcessorNew.php │ └── Writers │ ├── Atom │ └── AtomODataWriter.php │ ├── IODataWriter.php │ ├── Json │ ├── IndentedTextWriter.php │ ├── JsonLightMetadataLevel.php │ ├── JsonLightODataWriter.php │ ├── JsonODataV1Writer.php │ ├── JsonODataV2Writer.php │ ├── JsonWriter.php │ └── Scope.php │ ├── ODataWriterRegistry.php │ └── ResponseWriter.php └── tests ├── IntegrationTests └── POData │ ├── Misc │ └── MiscTest.php │ ├── ObjectModel │ └── ObjectModelSerializerTest.php │ ├── OperationContext │ └── ServiceHostTest.php │ └── UriProcessor │ └── UriProcessorExecutionTest.php ├── UnitTests └── POData │ ├── BaseServiceDummy.php │ ├── BaseServiceGetResponseContentTest.php │ ├── BaseServiceNewTest.php │ ├── BaseServiceTest.php │ ├── BatchProcessor │ ├── BatchProcessorDummy.php │ ├── BatchProcessorTest.php │ ├── ChangeSetParserDummy.php │ ├── ChangeSetParserTest.php │ ├── IncomingChangeSetRequestDummy.php │ └── IncomingChangeSetRequestTest.php │ ├── Common │ ├── ErrorHandlerTest.php │ ├── HttpHeaderFailureTest.php │ ├── HttpStatusTest.php │ ├── MessagesTest.php │ ├── ODataExceptionTest.php │ ├── ReflectionHandlerTest.php │ ├── ServiceConfigurationTest.php │ ├── UrlTest.php │ └── VersionTest.php │ ├── Configuration │ └── ServiceConfigurationTest.php │ ├── Facets │ ├── BaseServiceTestWrapper.php │ ├── NorthWind1 │ │ ├── Address2.php │ │ ├── Address4.php │ │ ├── Customer2.php │ │ ├── Employee2.php │ │ ├── NorthWindExpressionProvider.php │ │ ├── NorthWindMetadata.php │ │ ├── NorthWindQueryProvider.php │ │ ├── NorthWindService2.php │ │ ├── NorthWindServiceV1.php │ │ ├── NorthWindServiceV3.php │ │ ├── Order2.php │ │ ├── OrderDetails2.php │ │ └── Product2.php │ ├── NorthWind2 │ │ └── NorthWindMetadata.php │ ├── NorthWind4 │ │ ├── NorthWindDSExpressionProvider4.php │ │ ├── NorthWindMetadata.php │ │ ├── NorthWindQueryProvider4.php │ │ ├── NorthWindService.php │ │ └── NorthWindStreamProvider4.php │ ├── ServiceHostTestFake.php │ └── WordPress2 │ │ ├── WordPressDSExpressionProvider.php │ │ ├── WordPressDataService.php │ │ ├── WordPressMetadata.php │ │ ├── WordPressQueryProvider.php │ │ └── humbug.json.dist │ ├── HttpProcessUtilityTest.php │ ├── IDSQP2 │ ├── NorthWind │ │ └── NorthWindSQLSRVTest.php │ └── WordPress │ │ └── WordPressMySQLTest.php │ ├── MediaTypeTest.php │ ├── ObjectModel │ ├── ODataEntryTest.php │ ├── ODataFeedTest.php │ ├── ODataLinkTest.php │ ├── ODataPropertyContentTest.php │ ├── ODataPropertyTest.php │ ├── ODataUrlTest.php │ ├── ObjectModelSerializerTest.php │ ├── Serialisers │ │ ├── CynicDeserialiserDummy.php │ │ ├── CynicSerialiserDummy.php │ │ ├── CynicSerialiserTest.php │ │ ├── ModelDeserialiserTest.php │ │ ├── ObjectDeserialiserCreateTest.php │ │ ├── ObjectDeserialiserFeedTest.php │ │ ├── ObjectDeserialiserOKTest.php │ │ ├── ObjectDeserialiserProcessedTest.php │ │ ├── SerialiserTestBase.php │ │ ├── SerialiserWriteBagTest.php │ │ ├── SerialiserWriteComplexTest.php │ │ ├── SerialiserWriteElementTest.php │ │ ├── SerialiserWriteElementsTest.php │ │ ├── SerialiserWritePrimitiveTest.php │ │ ├── SerialiserWriteUrlTest.php │ │ └── TestDataService.php │ ├── reusableEntityClass1.php │ ├── reusableEntityClass2.php │ └── reusableEntityClass3.php │ ├── OperationContext │ ├── ServiceHostTest.php │ ├── SimpleOperationContextTest.php │ ├── SimpleRequestAdapterTest.php │ └── Web │ │ ├── IncomingRequestTest.php │ │ ├── OutgoingResponseTest.php │ │ └── WebOperationContextTest.php │ ├── PluralizerTest.php │ ├── Providers │ ├── Expression │ │ ├── MySQLExpressionProviderErrorCheckTest.php │ │ ├── MySQLExpressionProviderTest.php │ │ ├── PHPExpressionProviderErrorCheckTest.php │ │ └── PHPExpressionProviderTest.php │ ├── Metadata │ │ ├── ResourceAssociationSetEndTest.php │ │ ├── ResourceAssociationSetTest.php │ │ ├── ResourceAssociationTypeEndTest.php │ │ ├── ResourceAssociationTypeTest.php │ │ ├── ResourceClassesTest.php │ │ ├── ResourceFunctionTypeTest.php │ │ ├── ResourcePropertyTest.php │ │ ├── ResourceSetWrapperTest.php │ │ ├── ResourceStreamInfoTest.php │ │ ├── ResourceTypeTest.php │ │ ├── SimpleMetadataProviderSingletonTest.php │ │ ├── SimpleMetadataProviderTest.php │ │ └── Type │ │ │ ├── BinaryTest.php │ │ │ ├── BooleanTest.php │ │ │ ├── ByteTest.php │ │ │ ├── CharTest.php │ │ │ ├── DateTimeTest.php │ │ │ ├── DecimalTest.php │ │ │ ├── DoubleTest.php │ │ │ ├── GuidTest.php │ │ │ ├── Int16Test.php │ │ │ ├── Int32Test.php │ │ │ ├── Int64Test.php │ │ │ ├── NavigationTest.php │ │ │ ├── Null1Test.php │ │ │ ├── SByteTest.php │ │ │ ├── SingleTest.php │ │ │ ├── StringTest.php │ │ │ └── VoidTest.php │ ├── ProvidersQueryWrapperTest.php │ ├── ProvidersWrapperMockeryTest.php │ ├── ProvidersWrapperTest.php │ ├── Query │ │ └── QueryResultTest.php │ └── Stream │ │ ├── SimpleStreamProviderTest.php │ │ └── StreamProviderWrapperTest.php │ ├── Readers │ └── Atom │ │ ├── AtomODataReaderTest.php │ │ ├── EntryProcessorTest.php │ │ ├── LinkProcessorTest.php │ │ └── ProcessPropertyTest.php │ ├── SimpleDataServiceTest.php │ ├── TestCase.php │ ├── UriProcessor │ ├── QueryProcessor │ │ ├── ExpandProjectionParser │ │ │ ├── ExpandTest.php │ │ │ ├── ExpandedProjectionNodeTest.php │ │ │ ├── RootProjectionNodeTest.php │ │ │ └── SelectTest.php │ │ ├── ExpressionParser │ │ │ ├── DummyExpressionParser.php │ │ │ ├── ExpressionLexerTest.php │ │ │ ├── ExpressionParser2Test.php │ │ │ ├── ExpressionParserTest.php │ │ │ ├── ExpressionTokenTest.php │ │ │ ├── Expressions │ │ │ │ ├── ArithmeticExpressionTest.php │ │ │ │ ├── ConstantExpressionTest.php │ │ │ │ ├── FunctionCallExpressionTest.php │ │ │ │ ├── PropertyAccessExpressionTest.php │ │ │ │ └── UnaryExpressionTest.php │ │ │ └── PHPExpressionProviderTest.php │ │ ├── FunctionDescriptionTest.php │ │ ├── OrderByParser │ │ │ ├── InternalOrderByInfoTest.php │ │ │ ├── OrderByInfoTest.php │ │ │ ├── OrderByLeafNodeTest.php │ │ │ ├── OrderByParserMockeryTest.php │ │ │ ├── OrderByParserTest.php │ │ │ └── OrderByPathSegmentTest.php │ │ ├── QueryProcessorTest.php │ │ └── SkipTokenParser │ │ │ ├── InternalSkipTokenInfoTest.php │ │ │ ├── SkipTokenInfoTest.php │ │ │ ├── SkipTokenParser2Test.php │ │ │ └── SkipTokenParserTest.php │ ├── RequestDescriptionJsonTest.php │ ├── RequestDescriptionMockeryTest.php │ ├── RequestDescriptionResponseVersionTest.php │ ├── RequestExpanderTest.php │ ├── ResourcePathProcessor │ │ └── SegmentParser │ │ │ ├── KeyDescriptorTest.php │ │ │ ├── SegmentDescriptorTest.php │ │ │ ├── SegmentParserMockeryTest.php │ │ │ ├── SegmentParserTest.php │ │ │ └── TargetKindTest.php │ ├── SegmentStackTest.php │ ├── UriProcessorDummy.php │ ├── UriProcessorMockeryTest.php │ ├── UriProcessorNew │ │ ├── ExecuteDeleteTest.php │ │ ├── ExecuteGetTest.php │ │ ├── ExecuteGetWithOptionsTest.php │ │ ├── ExecutePostTest.php │ │ ├── ExecutePutTest.php │ │ └── ProcessTest.php │ ├── UriProcessorNewTest.php │ └── UriProcessorTest.php │ └── Writers │ ├── Atom │ ├── AtomODataWriterDummy.php │ └── AtomODataWriterTest.php │ ├── BaseWriterTest.php │ ├── Json │ ├── IndentedTextWriterTest.php │ ├── JsonLightODataWriterFullMetadataTest.php │ ├── JsonLightODataWriterMinimalMetadataTest.php │ ├── JsonLightODataWriterNoMetadataTest.php │ ├── JsonODataV1WriterTest.php │ ├── JsonODataV2WriterTest.php │ ├── JsonWriterTest.php │ └── WriterFencePostTest.php │ ├── ODataWriterRegistryTest.php │ ├── ObjectModelsForTests.php │ └── ResponseWriterTest.php └── bootstrap.php /.github/actions/tag_bump/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine 2 | 3 | RUN apk --no-cache add bash git curl jq && npm install -g semver 4 | 5 | COPY entrypoint.sh /entrypoint.sh 6 | RUN ["chmod", "+x", "/entrypoint.sh"] 7 | ENTRYPOINT ["/entrypoint.sh"] -------------------------------------------------------------------------------- /.github/actions/tag_bump/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Github Tag Bump' 2 | description: 'Bump and push git tag on merge' 3 | author: 'Chris Harris' 4 | runs: 5 | using: 'docker' 6 | image: 'Dockerfile' 7 | outputs: 8 | new_tag: 9 | description: 'Generated tag' 10 | tag: 11 | description: 'The latest tag after running this action' 12 | part: 13 | description: 'The part of version which was bumped' 14 | branding: 15 | icon: 'git-merge' 16 | color: 'purple' -------------------------------------------------------------------------------- /.github/workflows/check_sem_ver.yml: -------------------------------------------------------------------------------- 1 | name: Check Semver 2 | 3 | on: 4 | pull_request: 5 | workflow_dispatch: 6 | jobs: 7 | semver: 8 | runs-on: ubuntu-latest 9 | name: Check Semantic Version Changes 10 | steps: 11 | - name: Checkout code 12 | uses: actions/checkout@v2 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Setup PHP 17 | uses: shivammathur/setup-php@v2 18 | with: 19 | php-version: ${{ matrix.php }} 20 | tools: composer:v2 21 | coverage: xdebug 22 | 23 | - name: Evaluate semantic versioning 24 | run: | 25 | wget https://psvcg.coreteks.org/php-semver-checker-git.phar 26 | php php-semver-checker-git.phar suggest -vvv --include-before=src --include-after=src --details --allow-detached -------------------------------------------------------------------------------- /.github/workflows/tag_latest.yml: -------------------------------------------------------------------------------- 1 | name: Commit Tag 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | tag-value: 7 | required: true 8 | dry-run: 9 | type: boolean 10 | description: should this be done as a dry run. 11 | default: true 12 | prefix-v: 13 | type: boolean 14 | description: should a v be appended to start of tag. 15 | default: false 16 | jobs: 17 | build: 18 | runs-on: ubuntu-22.04 19 | permissions: 20 | contents: write 21 | steps: 22 | - uses: actions/checkout@v3 23 | with: 24 | fetch-depth: '0' 25 | - name: Bump version and push tag 26 | uses: ./.github/actions/tag_bump 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # if you don't want to set write permissions use a PAT token 29 | WITH_V: ${{ github.event.inputs.prefix-v }} 30 | DRY_RUN: ${{ github.event.inputs.dry-run }} 31 | CUSTOM_TAG: ${{ github.event.inputs.tag-value }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea* 3 | *.iml 4 | vendor* 5 | atlassian-ide-plugin.xml 6 | composer.lock 7 | composer.phar 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 7.1 5 | - 7.2 6 | - 7.3 7 | - 7.4 8 | - nightly 9 | 10 | 11 | before_script: 12 | - pecl install pcov 13 | - phpenv config-rm xdebug.ini 14 | - composer global require hirak/prestissimo 15 | - composer config minimum-stability ${STABILITY} 16 | - COMPOSER_MEMORY_LIMIT=-1 composer install 17 | - vendor/bin/pcov clobber 18 | - cat composer.lock 19 | # - wget http://getcomposer.org/composer.phar 20 | # - php composer.phar require satooshi/php-coveralls:dev-master --dev --no-progress --prefer-source 21 | 22 | script: 23 | - mkdir -p build/logs 24 | # run tests in random order to expose hidden inter-test dependencies (by breakages) 25 | - php vendor/bin/phpunit --coverage-clover build/logs/clover.xml 26 | 27 | after_script: 28 | - php vendor/bin/php-coveralls --exclude-no-stmt 29 | 30 | after_success: 31 | - coveralls 32 | env: # important! 33 | - STABILITY=stable 34 | - STABILITY=dev 35 | matrix: 36 | allow_failures: 37 | - php: nightly 38 | 39 | #notifications: 40 | # webhooks: 41 | # urls: 42 | # # Send Hall Dev Loung a Message 43 | # - secure: "XgvziuMTeNM3DKo5VY6VQeIZyhuoNxtHBezXWpsy5eEqcEyciAOodTeW4La5kckEyu2MYC2r7Vek9jv9rshyyhP74NNugVJPt7OZeBtmjILvwjsUk+VJP6xzK+zxC3Xo57PxlSo4O8OMNJ3Is8Sc+6AJ9tbgx4KFkE2u3f3j/n8=" 44 | # on_start: true 45 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # POData Contributor's Guide 2 | 3 | Contribution policies, workflows, etc 4 | 5 | **Development practice** 6 | 7 | * **Don't break the project** 8 | If the Travis build doesn't pass cleanly, that's broken enough for us. 9 | The PHP-nightly-version builds are permitted to fail - when someone manages 10 | to drop the blocker out, they'll resume their early-warning role. 11 | 12 | * **Keep each pull request to one piece of conceptual work at a time** 13 | You can work on as many different features/bugfixen as you like, but one 14 | pull request for each, please. 15 | 16 | * **A given patch needs to fit comfortably in a single reviewer's head** 17 | Easy to review means easy to find and fix bugs before they land in 18 | mainline. Easy to review also means easy to approve and merge. 19 | 20 | * **Test your work** 21 | Changing code? Give us tests that show you've thought about your change, 22 | tested it, etc - and help us automatically check your changes. If you 23 | find (and fix) bugs in your change before we see it, so much the better. 24 | 25 | * **Don't break any existing tests** 26 | Every test that passed before your patch must pass afterwards. 27 | 28 | * **Don't reduce coverage level** 29 | High code coverage drives critical code review and shakes lots of bugs 30 | out. We've found keeping coverage high (95% or better) to be a very 31 | effective way of keeping the dev train steaming onwards at full throttle 32 | with a low bug load. Since we've all done it, you need to do it as well. 33 | 34 | * **Eat. Sleep. PSR-2. Repeat.** 35 | As POData is a Composer package, we apply the PSR-2 coding 36 | standard. Code formatted to one standard is a heck of a lot easier to 37 | read than code formatted to a jumble of "standards" - for instance, 38 | pre-Heartbleed OpenSSL. 39 | 40 | -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide.htm -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide.pdf -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/colorschememapping.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/filelist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image001.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image002.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image003.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image004.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image004.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image005.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image006.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image006.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image007.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image008.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image009.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image009.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image010.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image011.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image012.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image013.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image013.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image014.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image015.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image016.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image017.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image018.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image018.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image019.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image019.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image020.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image020.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image021.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image021.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image022.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image023.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image023.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image024.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image025.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image026.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image026.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image027.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image027.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image028.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image028.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image029.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image029.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image030.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image030.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image031.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image031.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image032.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image032.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image033.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image033.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image034.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image034.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image035.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image035.png -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image036.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image036.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image037.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image037.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/image038.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/image038.jpg -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/item0001.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/props002.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Docs/OData PHP Producer Library User Guide_files/themedata.thmx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Algo-Web/POData/f6e64f51634ec5966e9a1186dbbccc0ed9c30fd8/Docs/OData PHP Producer Library User Guide_files/themedata.thmx -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "algo-web/podata", 3 | "type": "library", 4 | "description": "OData for Poor PHP Developers", 5 | "keywords": [ "rest", "odata" ], 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "c-harris", 10 | "email": "c.harris@communicationinnovations.com.au" 11 | }, 12 | { 13 | "name": "Alex Goodwin", 14 | "email": "cyberia.resurrection@gmail.com" 15 | }, 16 | { 17 | "name": "POData Project", 18 | "email": "podataproject@gmail.com" 19 | }, 20 | { 21 | "name": "Microsoft Open Technologies, Inc.", 22 | "email": "msopentech@microsoft.com" 23 | } 24 | ], 25 | "minimum-stability": "dev", 26 | "require": { 27 | "myclabs/php-enum": "^1.7", 28 | "cruxinator/php-bitmask": "^0.1", 29 | "php": "^7.1", 30 | "doctrine/inflector":">=v1.0", 31 | "algo-web/o-data-metadata": "^0.1.3", 32 | "ext-xml": "*", 33 | "ext-xmlwriter": "*" 34 | }, 35 | "require-dev": { 36 | "nesbot/carbon": "^1.0|^2.0", 37 | "pcov/clobber": "dev-master", 38 | "php-coveralls/php-coveralls": ">=v2.1", 39 | "phpunit/phpunit": "^7.0", 40 | "mockery/mockery": "^1.2|dev-master", 41 | "symfony/var-dumper": ">=4.0.0" 42 | }, 43 | 44 | "autoload": { 45 | "psr-4": { 46 | "POData\\": "src/POData/" 47 | } 48 | }, 49 | "autoload-dev": { 50 | "psr-4": { 51 | "UnitTests\\POData\\": "tests/UnitTests/POData/" 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | 17 | ./tests/UnitTests 18 | 19 | 20 | 21 | 22 | src/ 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/POData/BatchProcessor/IBatchParser.php: -------------------------------------------------------------------------------- 1 | statusCode = $statusCode; 26 | if (null !== $errorCode) { 27 | parent::__construct($message, $errorCode); 28 | } 29 | parent::__construct($message, $statusCode); 30 | } 31 | 32 | /** 33 | * Get the status code. 34 | * 35 | * @return int 36 | */ 37 | public function getStatusCode() 38 | { 39 | return $this->statusCode; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/POData/Common/InvalidOperationException.php: -------------------------------------------------------------------------------- 1 | {$property}; 28 | } else { 29 | if (null === $entryObject) { 30 | $msg = 'Property POData\\Common\\ReflectionHandler::$' . $property . ' does not exist'; 31 | throw new ReflectionException($msg); 32 | } 33 | $reflectionProperty = new ReflectionProperty(get_class($entryObject), $property); 34 | $reflectionProperty->setAccessible(true); 35 | $value = $reflectionProperty->getValue($entryObject); 36 | } 37 | 38 | return $value; 39 | } 40 | 41 | /** 42 | * @param object $entity 43 | * @param string $property 44 | * @param mixed $value 45 | * @throws ReflectionException 46 | */ 47 | public static function setProperty(&$entity, $property, $value) 48 | { 49 | // If magic method exists, try that first, else try property directly 50 | if (method_exists($entity, '__set')) { 51 | $entity->{$property} = $value; 52 | } else { 53 | $reflect = new ReflectionProperty($entity, $property); 54 | $oldAccess = $reflect->isPublic(); 55 | $reflect->setAccessible(true); 56 | $reflect->setValue($entity, $value); 57 | $reflect->setAccessible($oldAccess); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/POData/Common/UrlFormatException.php: -------------------------------------------------------------------------------- 1 | name = $name; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/AtomObjectModel/AtomContent.php: -------------------------------------------------------------------------------- 1 | src = $src; 43 | $this->type = $type; 44 | $this->properties = $properties; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/IOData.php: -------------------------------------------------------------------------------- 1 | setType($type) 37 | ->setPropertyContents($propertyContents); 38 | } 39 | 40 | /** 41 | * @return string|null 42 | */ 43 | public function getType(): ?string 44 | { 45 | return $this->type; 46 | } 47 | 48 | /** 49 | * @param string|null $type 50 | * @return ODataBagContent 51 | */ 52 | public function setType(?string $type): ODataBagContent 53 | { 54 | $this->type = $type; 55 | return $this; 56 | } 57 | 58 | /** 59 | * @return ODataPropertyContent[]|string[] 60 | */ 61 | public function getPropertyContents(): ?array 62 | { 63 | return $this->propertyContents; 64 | } 65 | 66 | /** 67 | * @param ODataPropertyContent[]|string[] $propertyContents 68 | * @return ODataBagContent 69 | */ 70 | public function setPropertyContents(?array $propertyContents): ODataBagContent 71 | { 72 | $this->propertyContents = $propertyContents; 73 | return $this; 74 | } 75 | 76 | public function addPropertyContent($propertyContent) 77 | { 78 | $this->propertyContents[] = $propertyContent; 79 | return $this; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/ODataCategory.php: -------------------------------------------------------------------------------- 1 | setTerm($term) 37 | ->setScheme($scheme); 38 | } 39 | 40 | /** 41 | * @return string 42 | */ 43 | public function getTerm(): string 44 | { 45 | return $this->term; 46 | } 47 | 48 | /** 49 | * @param string $term 50 | * @return ODataCategory 51 | */ 52 | public function setTerm(string $term): ODataCategory 53 | { 54 | $this->term = $term; 55 | return $this; 56 | } 57 | 58 | /** 59 | * @return string 60 | */ 61 | public function getScheme(): string 62 | { 63 | return $this->scheme; 64 | } 65 | 66 | /** 67 | * @param string $scheme 68 | * @return ODataCategory 69 | */ 70 | public function setScheme(string $scheme): ODataCategory 71 | { 72 | $this->scheme = $scheme; 73 | return $this; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/ODataExpandedResult.php: -------------------------------------------------------------------------------- 1 | {$data instanceof ODataEntry ? 'setEntry' : 'setFeed'}($data); 33 | } 34 | 35 | /** 36 | * @return ODataEntry|null 37 | */ 38 | public function getEntry(): ?ODataEntry 39 | { 40 | return $this->data instanceof ODataEntry ? $this->data : null; 41 | } 42 | 43 | /** 44 | * @param ODataEntry $entry 45 | * @return ODataExpandedResult 46 | */ 47 | public function setEntry(ODataEntry $entry): ODataExpandedResult 48 | { 49 | $this->data = $entry; 50 | return $this; 51 | } 52 | 53 | /** 54 | * @return ODataFeed|null 55 | */ 56 | public function getFeed(): ?ODataFeed 57 | { 58 | return $this->data instanceof ODataFeed ? $this->data : null; 59 | } 60 | 61 | /** 62 | * @param ODataFeed $feed 63 | * @return ODataExpandedResult 64 | */ 65 | public function setFeed(ODataFeed $feed): ODataExpandedResult 66 | { 67 | $this->data = $feed; 68 | return $this; 69 | } 70 | 71 | /** 72 | * @return ODataContainerBase 73 | */ 74 | public function getData(): ODataContainerBase 75 | { 76 | return $this->data; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/ODataMediaLink.php: -------------------------------------------------------------------------------- 1 | contentType = $contentType; 71 | $this->editLink = $editLink; 72 | $this->eTag = $eTag; 73 | $this->name = $name; 74 | $this->srcLink = $srcLink; 75 | $this->rel = (null !== $rel) ? $rel : 76 | ODataConstants::ATOM_MEDIA_RESOURCE_RELATION_ATTRIBUTE_VALUE . $name; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/ODataNextPageLink.php: -------------------------------------------------------------------------------- 1 | setTitle($title) 39 | ->setType($type); 40 | } 41 | 42 | /** 43 | * @return string 44 | */ 45 | public function getTitle(): string 46 | { 47 | return $this->title; 48 | } 49 | 50 | /** 51 | * @param string $title 52 | * @return ODataTitle 53 | */ 54 | public function setTitle(string $title): ODataTitle 55 | { 56 | $this->title = $title; 57 | return $this; 58 | } 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function getType(): string 64 | { 65 | return $this->type; 66 | } 67 | 68 | /** 69 | * @param string $type 70 | * @return ODataTitle 71 | */ 72 | public function setType(string $type): ODataTitle 73 | { 74 | $this->type = $type; 75 | return $this; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/ODataURL.php: -------------------------------------------------------------------------------- 1 | setUrl($url); 28 | } 29 | 30 | /** 31 | * @return string 32 | */ 33 | public function getUrl(): string 34 | { 35 | return $this->url; 36 | } 37 | 38 | /** 39 | * @param string $url 40 | * @return ODataURL 41 | */ 42 | public function setUrl(string $url): ODataURL 43 | { 44 | $this->url = $url; 45 | return $this; 46 | } 47 | 48 | /** 49 | * @param string|null $msg 50 | * @return bool 51 | */ 52 | public function isOk(&$msg = null): bool 53 | { 54 | if (null == $this->url || empty($this->url)) { 55 | $msg = 'Url value must be non-empty'; 56 | return false; 57 | } 58 | return true; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/ODataURLCollection.php: -------------------------------------------------------------------------------- 1 | setUrls($urls) 41 | ->setNextPageLink($nextPageLink) 42 | ->setCount($count); 43 | } 44 | /** 45 | * @return ODataURL[] 46 | */ 47 | public function getUrls(): array 48 | { 49 | return $this->urls; 50 | } 51 | 52 | /** 53 | * @param ODataURL[] $urls 54 | * @return ODataURLCollection 55 | */ 56 | public function setUrls(array $urls): ODataURLCollection 57 | { 58 | $this->urls = $urls; 59 | return $this; 60 | } 61 | 62 | /** 63 | * @return ODataNextPageLink|null 64 | */ 65 | public function getNextPageLink(): ?ODataNextPageLink 66 | { 67 | return $this->nextPageLink; 68 | } 69 | 70 | /** 71 | * @param ODataNextPageLink|null $nextPageLink 72 | * @return ODataURLCollection 73 | */ 74 | public function setNextPageLink(?ODataNextPageLink $nextPageLink): ODataURLCollection 75 | { 76 | $this->nextPageLink = $nextPageLink; 77 | return $this; 78 | } 79 | 80 | /** 81 | * @return int|null 82 | */ 83 | public function getCount(): ?int 84 | { 85 | return $this->count; 86 | } 87 | 88 | /** 89 | * @param int|null $count 90 | * @return ODataURLCollection 91 | */ 92 | public function setCount(?int $count): ODataURLCollection 93 | { 94 | $this->count = $count; 95 | return $this; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/POData/ObjectModel/ObjectModelSerializer.php: -------------------------------------------------------------------------------- 1 | request = new SimpleRequestAdapter($request); 27 | $this->response = new OutgoingResponse(); 28 | } 29 | 30 | /** 31 | * Gets the Web request context for the request being sent. 32 | * 33 | * @return OutgoingResponse reference of OutgoingResponse object 34 | */ 35 | public function outgoingResponse(): OutgoingResponse 36 | { 37 | return $this->response; 38 | } 39 | 40 | /** 41 | * Gets the Web request context for the request being received. 42 | * 43 | * @return IHTTPRequest reference of IncomingRequest object 44 | */ 45 | public function incomingRequest(): IHTTPRequest 46 | { 47 | return $this->request; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/POData/OperationContext/SimpleRequestAdapter.php: -------------------------------------------------------------------------------- 1 | request = $request; 24 | } 25 | 26 | /** 27 | * get the raw incoming url. 28 | * 29 | * @return string RequestURI called by User with the value of QueryString 30 | */ 31 | public function getRawUrl(): string 32 | { 33 | return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . '/' . $_SERVER['REQUEST_URI']; 34 | } 35 | 36 | /** 37 | * Returns the Query String Parameters (QSPs) as an array of KEY-VALUE pairs. If a QSP appears twice 38 | * it will have two entries in this array. 39 | * 40 | * @return array[] 41 | */ 42 | public function getQueryParameters(): array 43 | { 44 | $data = []; 45 | if (is_array($this->request)) { 46 | foreach ($this->request as $key => $value) { 47 | $data[] = [$key => $value]; 48 | } 49 | } 50 | 51 | return $data; 52 | } 53 | 54 | /** 55 | * Get the HTTP method/verb of the HTTP Request. 56 | * 57 | * @return HTTPRequestMethod 58 | */ 59 | public function getMethod(): HTTPRequestMethod 60 | { 61 | return new HTTPRequestMethod($_SERVER['REQUEST_METHOD']); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/POData/OperationContext/Web/WebOperationContext.php: -------------------------------------------------------------------------------- 1 | incomingRequest = $incomingRequest ?? new IncomingRequest(); 46 | $this->outgoingResponse = $outgoingResponse ?? new OutgoingResponse(); 47 | } 48 | 49 | /** 50 | * Gets the Web request context for the request being sent. 51 | * 52 | * @return OutgoingResponse 53 | */ 54 | public function outgoingResponse(): OutgoingResponse 55 | { 56 | return $this->outgoingResponse; 57 | } 58 | 59 | /** 60 | * Gets the Web request context for the request being received. 61 | * 62 | * @return IHTTPRequest 63 | */ 64 | public function incomingRequest(): IHTTPRequest 65 | { 66 | return $this->incomingRequest; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/POData/Providers/Metadata/EdmSchemaVersion.php: -------------------------------------------------------------------------------- 1 | getName()); 28 | $name = array_pop($bitz); 29 | $namespaceName = null; 30 | if (0 < count($bitz)) { 31 | $namespaceName = implode('.', $bitz); 32 | } 33 | $baseType = null; 34 | $isAbstract = false; 35 | parent::__construct($instanceType, $resourceTypeKind, $name, $namespaceName, $baseType, $isAbstract); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/POData/Providers/Metadata/ResourceEntityType.php: -------------------------------------------------------------------------------- 1 | getName()); 29 | $name = array_pop($bitz); 30 | $namespaceName = $meta->getContainerNamespace(); 31 | if (0 < count($bitz)) { 32 | $namespaceName = implode('.', $bitz); 33 | } 34 | $rawType = $entity->getBaseType(); 35 | $metaNamespace = $namespaceName . '.'; 36 | 37 | $rawType = (null !== $rawType) ? str_replace($metaNamespace, '', $rawType) : null; 38 | $baseType = null === $rawType ? null : $meta->resolveResourceType($rawType); 39 | assert(isset($rawType) === isset($baseType), 'Base and raw type nullity inconsistent'); 40 | 41 | $isAbstract = $entity->getAbstract(); 42 | parent::__construct($instanceType, $resourceTypeKind, $name, $namespaceName, $baseType, $isAbstract); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/POData/Providers/Metadata/ResourcePrimitiveType.php: -------------------------------------------------------------------------------- 1 | getName()); 26 | $name = array_pop($bitz); 27 | $namespaceName = null; 28 | if (0 < count($bitz)) { 29 | $namespaceName = implode('.', $bitz); 30 | } 31 | $baseType = null; 32 | $isAbstract = false; 33 | parent::__construct($primitive, $resourceTypeKind, $name, $namespaceName, $baseType, $isAbstract); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/POData/Providers/Metadata/ResourcePropertyKind.php: -------------------------------------------------------------------------------- 1 | name = $name; 42 | $this->resourceType = $resourceType; 43 | } 44 | 45 | /** 46 | * Get the container name. 47 | * 48 | * @return string 49 | */ 50 | public function getName(): string 51 | { 52 | return $this->name; 53 | } 54 | 55 | /** 56 | * Get the type hold by this container. 57 | * 58 | * @return ResourceEntityType 59 | */ 60 | public function getResourceType(): ResourceEntityType 61 | { 62 | return $this->resourceType; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/POData/Providers/Metadata/ResourceStreamInfo.php: -------------------------------------------------------------------------------- 1 | name = $name; 30 | } 31 | 32 | /** 33 | * Gets name of the stream. 34 | * 35 | * @return string 36 | */ 37 | public function getName(): string 38 | { 39 | return $this->name; 40 | } 41 | 42 | /** 43 | * Gets custom state. 44 | * 45 | * @return object 46 | */ 47 | public function getCustomState() 48 | { 49 | return $this->customState; 50 | } 51 | 52 | /** 53 | * Sets custom state. 54 | * 55 | * @param object $stateObject The custom object 56 | */ 57 | public function setCustomState($stateObject) 58 | { 59 | $this->customState = $stateObject; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/POData/Providers/Metadata/ResourceTypeKind.php: -------------------------------------------------------------------------------- 1 | results = $results; 39 | $this->count = $count; 40 | $this->hasMore = $hasMore; 41 | } 42 | 43 | /** 44 | * @param int $count 45 | * @param int|null $top 46 | * @param int|null $skip 47 | * 48 | * @throws InvalidArgumentException if $count is not numeric 49 | * @return int the paging adjusted count 50 | */ 51 | public static function adjustCountForPaging(int $count, ?int $top, ?int $skip) 52 | { 53 | //treat nulls like 0 54 | if (null === $skip) { 55 | $skip = 0; 56 | } 57 | 58 | $count = $count - $skip; //eliminate the skipped records 59 | if ($count < 0) { 60 | return 0; 61 | } //if there aren't enough to skip, the count is 0 62 | 63 | if (null === $top) { 64 | return $count; 65 | } //if there's no top, then it's the count as is 66 | 67 | return intval(min($count, $top)); //count is top, unless there aren't enough records 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/POData/Providers/Query/QueryType.php: -------------------------------------------------------------------------------- 1 | readers[] = $reader; 25 | } 26 | 27 | /** 28 | * @param Version $responseVersion 29 | * @param $contentType 30 | * 31 | * @return IODataReader|null the writer that can handle the given criteria, or null 32 | */ 33 | public function getReader(Version $responseVersion, $contentType) 34 | { 35 | foreach ($this->readers as $reader) { 36 | if ($reader->canHandle($responseVersion, $contentType)) { 37 | return $reader; 38 | } 39 | } 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/Interfaces/IUriProcessor.php: -------------------------------------------------------------------------------- 1 | nodeType; 36 | } 37 | 38 | /** 39 | * Get the expression type. 40 | * 41 | * @return IType 42 | */ 43 | public function getType(): IType 44 | { 45 | return $this->type; 46 | } 47 | 48 | /** 49 | * Set the expression type. 50 | * 51 | * @param IType $type The type to set as expression type 52 | * 53 | * @return void 54 | */ 55 | public function setType(IType $type): void 56 | { 57 | $this->type = $type; 58 | } 59 | 60 | /** 61 | * Checks expression is a specific type. 62 | * 63 | * @param IType $type The type to check 64 | * 65 | * @return bool 66 | */ 67 | public function typeIs(IType $type): bool 68 | { 69 | return $this->type->getTypeCode() == $type->getTypeCode(); 70 | } 71 | 72 | /** 73 | * Frees the resources hold by this expression. 74 | * 75 | * @return void 76 | */ 77 | abstract public function free(): void; 78 | } 79 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/ArithmeticExpression.php: -------------------------------------------------------------------------------- 1 | nodeType = $nodeType; 29 | $this->type = $type; 30 | parent::__construct($left, $right); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/BinaryExpression.php: -------------------------------------------------------------------------------- 1 | left = $left; 33 | $this->right = $right; 34 | } 35 | 36 | /** 37 | * Get left operand (expression) of binary expression. 38 | * 39 | * @return AbstractExpression|null 40 | */ 41 | public function getLeft(): ?AbstractExpression 42 | { 43 | return isset($this->left) ? $this->left : null; 44 | } 45 | 46 | /** 47 | * Set left operand (expression) of binary expression. 48 | * 49 | * @param AbstractExpression $expression Expression to set as left operand 50 | */ 51 | public function setLeft(AbstractExpression $expression): void 52 | { 53 | $this->left = $expression; 54 | } 55 | 56 | /** 57 | * Get right operand (expression) of binary expression. 58 | * 59 | * @return AbstractExpression|null 60 | */ 61 | public function getRight(): ?AbstractExpression 62 | { 63 | return isset($this->right) ? $this->right : null; 64 | } 65 | 66 | /** 67 | * Set right operand (expression) of binary expression. 68 | * 69 | * @param AbstractExpression $expression Expression to set as right operand 70 | */ 71 | public function setRight(AbstractExpression $expression): void 72 | { 73 | $this->right = $expression; 74 | } 75 | 76 | /** 77 | * (non-PHPdoc). 78 | * 79 | * @see library/POData/QueryProcessor/ExpressionParser/Expressions.AbstractExpression::free() 80 | */ 81 | public function free(): void 82 | { 83 | $this->left->free(); 84 | $this->right->free(); 85 | unset($this->left); 86 | unset($this->right); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/ConstantExpression.php: -------------------------------------------------------------------------------- 1 | value = $value; 30 | $this->nodeType = ExpressionType::CONSTANT(); 31 | $this->type = $type; 32 | } 33 | 34 | /** 35 | * Get the value associated with the expression. 36 | * 37 | * @return string|bool|null 38 | */ 39 | public function getValue() 40 | { 41 | return isset($this->value) ? $this->value : null; 42 | } 43 | 44 | /** 45 | * (non-PHPdoc). 46 | * 47 | * @return void 48 | * @see library/POData/QueryProcessor/ExpressionParser/Expressions.AbstractExpression::free() 49 | */ 50 | public function free(): void 51 | { 52 | unset($this->value); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/FunctionCallExpression.php: -------------------------------------------------------------------------------- 1 | $paramExpressions The parameters to the function 29 | */ 30 | public function __construct(FunctionDescription $functionDescription, array $paramExpressions) 31 | { 32 | $this->functionDescription = $functionDescription; 33 | $this->paramExpressions = $paramExpressions; 34 | $this->nodeType = ExpressionType::CALL(); 35 | $this->type = $functionDescription->returnType; 36 | } 37 | 38 | /** 39 | * To get the array of expressions represents arguments of function. 40 | * 41 | * @return AbstractExpression[] 42 | */ 43 | public function getParamExpressions(): array 44 | { 45 | return $this->paramExpressions; 46 | } 47 | 48 | /** 49 | * To get description of the function this expression represents. 50 | * 51 | * @return FunctionDescription 52 | */ 53 | public function getFunctionDescription(): FunctionDescription 54 | { 55 | return $this->functionDescription; 56 | } 57 | 58 | /** 59 | * (non-PHPdoc). 60 | * 61 | * @see library/POData/QueryProcessor/ExpressionParser/Expressions.AbstractExpression::free() 62 | */ 63 | public function free(): void 64 | { 65 | $numExpr = count($this->paramExpressions); 66 | for ($i = $numExpr - 1; $i >= 0; $i--) { 67 | $this->paramExpressions[$i]->free(); 68 | unset($this->paramExpressions[$i]); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/LogicalExpression.php: -------------------------------------------------------------------------------- 1 | nodeType = $nodeType; 24 | $this->type = new Boolean(); 25 | parent::__construct($left, $right); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/RelationalExpression.php: -------------------------------------------------------------------------------- 1 | nodeType = $nodeType; 24 | $this->type = new Boolean(); 25 | parent::__construct($left, $right); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/UnaryExpression.php: -------------------------------------------------------------------------------- 1 | child = $child; 29 | //allowed unary operator are 'not' (ExpressionType::NOT_LOGICAL) 30 | //and ExpressionType::NEGATE 31 | $this->nodeType = $nodeType; 32 | $this->type = $type; 33 | } 34 | 35 | /** 36 | * To get the child. 37 | * 38 | * @return AbstractExpression|null 39 | */ 40 | public function getChild(): ?AbstractExpression 41 | { 42 | return isset($this->child) ? $this->child : null; 43 | } 44 | 45 | /** 46 | * (non-PHPdoc). 47 | * 48 | * @see library/POData/QueryProcessor/ExpressionParser/Expressions.AbstractExpression::free() 49 | */ 50 | public function free(): void 51 | { 52 | $this->child->free(); 53 | unset($this->child); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/ExpressionParser/FilterInfo.php: -------------------------------------------------------------------------------- 1 | |null 23 | */ 24 | private $navigationPropertiesUsedInTheFilterClause; 25 | 26 | /** 27 | * The translated expression based on the Expression provider, if the end developer 28 | * opt for IDSQP2 then he is responsible for implementing IExpressionProvider 29 | * in this case this member variable will hold the expression generated through 30 | * custom ExpressionProvider, if user opt for IDSQP then the default 31 | * PHPExpressionProvider will be used, in this case this member variable will 32 | * hold the PHP expression generated through the PHPExpressionProvider. 33 | * 34 | * @var string 35 | */ 36 | private $filterExpressionAsDataSourceExpression; 37 | 38 | /** 39 | * @param array $navigationProperties navigation properties in the $filter clause 40 | * @param string $filterExpAsDataSourceExp The $filter expression, specific to data source 41 | */ 42 | public function __construct(array $navigationProperties, string $filterExpAsDataSourceExp) 43 | { 44 | $this->navigationPropertiesUsedInTheFilterClause = $navigationProperties; 45 | $this->filterExpressionAsDataSourceExpression = $filterExpAsDataSourceExp; 46 | } 47 | 48 | /** 49 | * @return array|null 50 | */ 51 | public function getNavigationPropertiesUsed(): ?array 52 | { 53 | return $this->navigationPropertiesUsedInTheFilterClause; 54 | } 55 | 56 | /** 57 | * Gets the data source specific expression as string. 58 | * 59 | * @return string 60 | */ 61 | public function getExpressionAsString(): ?string 62 | { 63 | return $this->filterExpressionAsDataSourceExpression; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/OrderByParser/OrderByPathSegment.php: -------------------------------------------------------------------------------- 1 | orderBySubPathSegments = $orderBySubPathSegments; 53 | $this->isAscending = $isAscending; 54 | } 55 | 56 | /** 57 | * Gets collection of sub path segments that made up this path segment. 58 | * 59 | * @return OrderBySubPathSegment[] 60 | */ 61 | public function getSubPathSegments(): array 62 | { 63 | return $this->orderBySubPathSegments; 64 | } 65 | 66 | /** 67 | * Is sorting order is ascending or descending? 68 | * 69 | * @return bool Return true for ascending sort order, else false 70 | */ 71 | public function isAscending(): bool 72 | { 73 | return $this->isAscending; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/OrderByParser/OrderByRootNode.php: -------------------------------------------------------------------------------- 1 | baseResourceType = $baseResourceType; 41 | } 42 | 43 | /** 44 | * (non-PHPdoc). 45 | * 46 | * @return ResourceType 47 | * @see library/POData/QueryProcessorOrderByParser.OrderByNode::getResourceType() 48 | */ 49 | public function getResourceType(): ResourceType 50 | { 51 | return $this->baseResourceType; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/OrderByParser/OrderBySubPathSegment.php: -------------------------------------------------------------------------------- 1 | resourceProperty = $resourceProperty; 40 | } 41 | 42 | /** 43 | * Gets name of the sub path segment. 44 | * 45 | * @return string 46 | */ 47 | public function getName(): string 48 | { 49 | return $this->resourceProperty->getName(); 50 | } 51 | 52 | /** 53 | * Gets reference to the ResourceProperty instance corresponding to this sub path segment. 54 | * 55 | * @return ResourceProperty 56 | */ 57 | public function getResourceProperty(): ResourceProperty 58 | { 59 | return $this->resourceProperty; 60 | } 61 | 62 | /** 63 | * Gets instance type of the ResourceProperty instance corresponding to 64 | * this sub path segment If this sub path segment is last segment then 65 | * this function returns 'IType', otherwise 'ReflectionClass'. 66 | * 67 | * @throws ReflectionException 68 | * @return ReflectionClass|IType 69 | */ 70 | public function getInstanceType() 71 | { 72 | return $this->resourceProperty->getInstanceType(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/QueryProcessor/SkipTokenParser/SkipTokenInfo.php: -------------------------------------------------------------------------------- 1 | > 31 | */ 32 | private $orderByValuesInSkipToken; 33 | 34 | /** 35 | * Constructs a new instance of SkipTokenInfo. 36 | * 37 | * @param OrderByInfo &$orderByInfo Type holding information about the navigation properties 38 | * used in the orderby clause (if any) and orderby path 39 | * @param array> $orderByValuesInSkipToken Collection of values in the skiptoken corresponds 40 | * to the orderby path segments 41 | */ 42 | public function __construct(OrderByInfo &$orderByInfo, array $orderByValuesInSkipToken) 43 | { 44 | $this->orderByInfo = $orderByInfo; 45 | $this->orderByValuesInSkipToken = $orderByValuesInSkipToken; 46 | } 47 | 48 | /** 49 | * Get reference to the OrderByInfo instance holding information about the 50 | * navigation properties used in the orderby clause (if any) and orderby path. 51 | * 52 | * @return OrderByInfo 53 | */ 54 | public function getOrderByInfo(): OrderByInfo 55 | { 56 | return $this->orderByInfo; 57 | } 58 | 59 | /** 60 | * Gets collection of values in the skiptoken corresponds to the orderby 61 | * path segments. 62 | * 63 | * @return array> 64 | */ 65 | public function getOrderByKeysInToken(): array 66 | { 67 | return $this->orderByValuesInSkipToken; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/POData/UriProcessor/ResourcePathProcessor/SegmentParser/TargetSource.php: -------------------------------------------------------------------------------- 1 | type = $type; 30 | $this->objectCount = 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/POData/Writers/ODataWriterRegistry.php: -------------------------------------------------------------------------------- 1 | writers[] = $writer; 23 | } 24 | 25 | public function reset() 26 | { 27 | $this->writers = []; 28 | } 29 | 30 | /** 31 | * @param Version $responseVersion 32 | * @param $contentType 33 | * 34 | * @return IODataWriter|null the writer that can handle the give criteria, or null 35 | */ 36 | public function getWriter(Version $responseVersion, $contentType) 37 | { 38 | foreach ($this->writers as $writer) { 39 | if ($writer->canHandle($responseVersion, $contentType)) { 40 | return $writer; 41 | } 42 | } 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/BatchProcessor/BatchProcessorDummy.php: -------------------------------------------------------------------------------- 1 | changeSetProcessors = $processors; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/BatchProcessor/ChangeSetParserDummy.php: -------------------------------------------------------------------------------- 1 | rawUrl = $raw; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/BatchProcessor/IncomingChangeSetRequestTest.php: -------------------------------------------------------------------------------- 1 | makePartial(); 21 | 22 | $contentId = '1'; 23 | $contentIdValue = 'WTF'; 24 | 25 | $foo->setRawUrl('$1/Orders'); 26 | 27 | $foo->applyContentId($contentId, $contentIdValue); 28 | 29 | $expected = 'WTF/Orders'; 30 | $actual = $foo->getRawUrl(); 31 | $this->assertEquals($expected, $actual); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Common/HttpHeaderFailureTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('FAIL', $foo->getMessage()); 16 | $this->assertEquals(601, $foo->getStatusCode()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Common/HttpStatusTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($expected, $result); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Common/ODataExceptionTest.php: -------------------------------------------------------------------------------- 1 | getMessage(); 17 | $this->assertEquals($expected, $actual); 18 | $this->assertEquals(403, $foo->getStatusCode()); 19 | } 20 | 21 | public function testCreatePreconditionFailedODataException() 22 | { 23 | $condition = 'foo == bar'; 24 | $foo = ODataException::createPreConditionFailedError($condition); 25 | $expected = 'foo == bar'; 26 | $actual = $foo->getMessage(); 27 | $this->assertEquals($expected, $actual); 28 | $this->assertEquals(412, $foo->getStatusCode()); 29 | } 30 | 31 | public function testCreateUnacceptableValueODataException() 32 | { 33 | $value = '$i < 0'; 34 | $foo = ODataException::notAcceptableError($value); 35 | $expected = '$i < 0'; 36 | $actual = $foo->getMessage(); 37 | $this->assertEquals($expected, $actual); 38 | $this->assertEquals(406, $foo->getStatusCode()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Common/ReflectionHandlerTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($expected, $actual); 21 | } 22 | 23 | public function testSetGetMagicMethod() 24 | { 25 | $expected = 'oldName'; 26 | $foo = new reusableEntityClass2('name', 'type'); 27 | ReflectionHandler::setProperty($foo, 'name', 'oldName'); 28 | $actual = ReflectionHandler::getProperty($foo, 'name'); 29 | $this->assertEquals($expected, $actual); 30 | } 31 | } 32 | 33 | class reflectionTest1 34 | { 35 | private $name; 36 | 37 | public function __construct($name) 38 | { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Common/ServiceConfigurationTest.php: -------------------------------------------------------------------------------- 1 | setUseVerboseErrors(true); 20 | $this->assertTrue($foo->getUseVerboseErrors()); 21 | } 22 | 23 | public function testEntitySetPageSizeRoundTrip() 24 | { 25 | $resource = m::mock(ResourceSet::class); 26 | $resource->shouldReceive('getName')->andReturn('entity'); 27 | 28 | $meta = m::mock(IMetadataProvider::class); 29 | $meta->shouldReceive('resolveResourceSet')->andReturn($resource); 30 | 31 | $foo = new ServiceConfiguration($meta); 32 | $foo->setEntitySetPageSize('entity', PHP_INT_MAX); 33 | $this->assertEquals(0, $foo->getEntitySetPageSize($resource)); 34 | } 35 | 36 | public function testEntitySetNegativePageSizeBlowsUpWithInvalidArgumentException() 37 | { 38 | $resource = m::mock(ResourceSet::class); 39 | $resource->shouldReceive('getName')->andReturn('entity'); 40 | 41 | $meta = m::mock(IMetadataProvider::class); 42 | $meta->shouldReceive('resolveResourceSet')->andReturn(true); 43 | 44 | $foo = new ServiceConfiguration($meta); 45 | 46 | $this->expectException(\InvalidArgumentException::class); 47 | $this->expectExceptionMessage('The argument to the function setEntitySetPageSize should be non-negative, negative value \'-1\' passed'); 48 | 49 | $foo->setEntitySetPageSize('entity', -1); 50 | } 51 | 52 | public function testValidateETagHeaderRoundTrip() 53 | { 54 | $meta = m::mock(IMetadataProvider::class); 55 | 56 | $foo = new ServiceConfiguration($meta); 57 | $foo->setValidateETagHeader(true); 58 | $this->assertTrue($foo->getValidateETagHeader()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Common/VersionTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(0, $version1->compare($version2)); 23 | } 24 | 25 | public function testCompareMajorSameMinorLess() 26 | { 27 | $version1 = new Version(1, 0); 28 | $version2 = new Version(1, 1); 29 | $this->assertEquals(-1, $version1->compare($version2)); 30 | } 31 | 32 | public function testCompareMajorSameMinorMore() 33 | { 34 | $version1 = new Version(1, 1); 35 | $version2 = new Version(1, 0); 36 | $this->assertEquals(1, $version1->compare($version2)); 37 | } 38 | 39 | public function testCompareMajorLessMinorSame() 40 | { 41 | $version1 = new Version(1, 0); 42 | $version2 = new Version(2, 0); 43 | $this->assertEquals(-1, $version1->compare($version2)); 44 | $this->assertEquals(+1, $version2->compare($version1)); 45 | } 46 | 47 | public function testCompareMajorMoreMinorLess() 48 | { 49 | $version1 = new Version(2, 0); 50 | $version2 = new Version(1, 1); 51 | $this->assertEquals(1, $version1->compare($version2)); 52 | } 53 | 54 | public function testRaiseVersion() 55 | { 56 | $version = new Version(2, 0); 57 | 58 | $version->raiseVersion(1, 5); 59 | $this->assertEquals(2, $version->getMajor()); 60 | $this->assertEquals(0, $version->getMinor()); 61 | 62 | $version->raiseVersion(3, 0); 63 | $this->assertEquals(3, $version->getMajor()); 64 | $this->assertEquals(0, $version->getMinor()); 65 | 66 | $version->raiseVersion(3, 1); 67 | $this->assertEquals(3, $version->getMajor()); 68 | $this->assertEquals(1, $version->getMinor()); 69 | } 70 | 71 | public function testStaticFunctionV1() 72 | { 73 | $version = Version::v1(); 74 | $this->assertEquals(1, $version->getMajor()); 75 | $this->assertEquals(0, $version->getMinor()); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Facets/BaseServiceTestWrapper.php: -------------------------------------------------------------------------------- 1 | createProviders(); 27 | $this->getHost()->validateQueryParameters(); 28 | 29 | return UriProcessor::process($this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Facets/NorthWind1/Address2.php: -------------------------------------------------------------------------------- 1 | setHost($serviceHost); 22 | parent::__construct(null); 23 | } 24 | 25 | /** 26 | * This method is called only once to initialize service-wide policies. 27 | * 28 | * @param IServiceConfiguration $config 29 | */ 30 | public function initialize(IServiceConfiguration $config) 31 | { 32 | $config->setEntitySetPageSize('*', 5); 33 | $config->setEntitySetAccessRule('*', EntitySetRights::ALL()); 34 | $config->setAcceptCountRequests(true); 35 | $config->setAcceptProjectionRequests(true); 36 | $config->setMaxDataServiceVersion(ProtocolVersion::V2()); 37 | } 38 | 39 | /** 40 | * @return \POData\Providers\Metadata\IMetadataProvider 41 | */ 42 | public function getMetadataProvider() 43 | { 44 | return NorthWindMetadata::Create(); 45 | } 46 | 47 | /** 48 | * @return \POData\Providers\Query\IQueryProvider 49 | */ 50 | public function getQueryProvider(): ?IQueryProvider 51 | { 52 | return new NorthWindQueryProvider(); 53 | } 54 | 55 | public function getStreamProviderX() 56 | { 57 | throw new NotImplementedException('not implemented'); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Facets/NorthWind1/NorthWindServiceV1.php: -------------------------------------------------------------------------------- 1 | setHost($serviceHost); 21 | parent::__construct(null); 22 | } 23 | 24 | /** 25 | * This method is called only once to initialize service-wide policies. 26 | * 27 | * @param IServiceConfiguration $config 28 | */ 29 | public function initialize(IServiceConfiguration $config) 30 | { 31 | $config->setEntitySetAccessRule('*', EntitySetRights::ALL()); 32 | //we are using V1 protocol, but still we set page size because with 33 | //a top value which is less than pagesize we can use V1 protocol 34 | //even though paging is enabled. 35 | $config->setEntitySetPageSize('*', 5); 36 | $config->setAcceptCountRequests(true); 37 | $config->setAcceptProjectionRequests(true); 38 | $config->setMaxDataServiceVersion(ProtocolVersion::V1()); 39 | } 40 | 41 | /** 42 | * @return \POData\Providers\Metadata\IMetadataProvider 43 | */ 44 | public function getMetadataProvider() 45 | { 46 | return NorthWindMetadata::Create(); 47 | } 48 | 49 | /** 50 | * @return \POData\Providers\Query\IQueryProvider 51 | */ 52 | public function getQueryProvider(): IQueryProvider 53 | { 54 | return new NorthWindQueryProvider(); 55 | } 56 | 57 | public function getStreamProviderX() 58 | { 59 | throw new Exception('not implemented'); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Facets/NorthWind1/NorthWindServiceV3.php: -------------------------------------------------------------------------------- 1 | setHost($serviceHost); 19 | parent::__construct(null); 20 | } 21 | 22 | /** 23 | * This method is called only once to initialize service-wide policies. 24 | * 25 | * @param IServiceConfiguration $config 26 | */ 27 | public function initialize(IServiceConfiguration $config) 28 | { 29 | $config->setEntitySetPageSize('*', 5); 30 | $config->setEntitySetAccessRule('*', EntitySetRights::ALL()); 31 | $config->setAcceptCountRequests(true); 32 | //Disable projection request for testing purpose 33 | $config->setAcceptProjectionRequests(false); 34 | $config->setMaxDataServiceVersion(ProtocolVersion::V3()); 35 | } 36 | 37 | /** 38 | * @return \POData\Providers\Metadata\IMetadataProvider 39 | */ 40 | public function getMetadataProvider() 41 | { 42 | return NorthWindMetadata::Create(); 43 | } 44 | 45 | /** 46 | * @return \POData\Providers\Query\IQueryProvider 47 | */ 48 | public function getQueryProvider(): ?IQueryProvider 49 | { 50 | return new NorthWindQueryProvider(); 51 | } 52 | 53 | public function getStreamProviderX() 54 | { 55 | throw new Exception('not implemented'); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Facets/NorthWind1/Order2.php: -------------------------------------------------------------------------------- 1 | assertEquals(0, count($foo->getParameters())); 21 | } 22 | 23 | public function testGetMatchingRatingOnUniversalMatch() 24 | { 25 | $foo = new MediaType('*', '*', []); 26 | 27 | $expected = 0; 28 | $actual = $foo->getMatchingRating('application/json'); 29 | $this->assertEquals($expected, $actual); 30 | } 31 | 32 | public function testGetMatchingRatingOnUniversalSubtypeMatch() 33 | { 34 | $foo = new MediaType('application', '*', []); 35 | 36 | $expected = 1; 37 | $actual = $foo->getMatchingRating('application/json'); 38 | $this->assertEquals($expected, $actual); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/ODataFeedTest.php: -------------------------------------------------------------------------------- 1 | setUrl('http://localhost/odata.svc'); 28 | 29 | $foo->setNextPageLink($bar); 30 | $this->assertNotNull($foo->getNextPageLink()); 31 | } 32 | 33 | public function testSetNextPageLinkBlank() 34 | { 35 | $foo = new ODataFeed(); 36 | $bar = new ODataLink(); 37 | 38 | $foo->setNextPageLink($bar); 39 | $this->assertNull($foo->getNextPageLink()); 40 | } 41 | 42 | public function testSetGetEntriesRoundTrip() 43 | { 44 | $entry = new ODataEntry(); 45 | $foo = new ODataFeed(); 46 | 47 | $foo->setEntries([$entry]); 48 | 49 | $this->assertEquals(1, count($foo->getEntries())); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/ODataLinkTest.php: -------------------------------------------------------------------------------- 1 | setExpandedResult($expand); 24 | $result = $foo->getExpandedResult(); 25 | 26 | $this->assertNotNull($result->getEntry()); 27 | $this->assertNull($result->getFeed()); 28 | } 29 | 30 | public function testSetGetODataFeedAsExpandedResult() 31 | { 32 | $entry = new ODataFeed(); 33 | $expand = new ODataExpandedResult($entry); 34 | 35 | $foo = new ODataLink(); 36 | $foo->setExpandedResult($expand); 37 | $result = $foo->getExpandedResult(); 38 | 39 | $this->assertNull($result->getEntry()); 40 | $this->assertNotNull($result->getFeed()); 41 | } 42 | 43 | public function testGetExpandedResultOnEmptyLink() 44 | { 45 | $foo = new ODataLink(); 46 | $this->assertNull($foo->getExpandedResult()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/ODataPropertyContentTest.php: -------------------------------------------------------------------------------- 1 | makePartial(); 22 | 23 | $this->assertTrue(isset($foo[1])); 24 | 25 | unset($foo[1]); 26 | $this->assertFalse(isset($foo[1])); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/ODataPropertyTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($foo->isNull()); 22 | } 23 | 24 | public function testIsNotNull() 25 | { 26 | $foo = new ODataProperty('', '', 'var'); 27 | 28 | $this->assertNull($foo->isNull()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/ODataUrlTest.php: -------------------------------------------------------------------------------- 1 | assertFalse($foo->isOk($actual)); 22 | $this->assertNotNull($actual); 23 | $this->assertEquals($expected, $actual); 24 | } 25 | 26 | public function testOkWhenNonEmptyUrl() 27 | { 28 | $foo = new ODataURL('url'); 29 | $expected = null; 30 | $actual = null; 31 | 32 | $this->assertTrue($foo->isOk($actual)); 33 | $this->assertNull($actual); 34 | $this->assertEquals($expected, $actual); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/Serialisers/CynicDeserialiserDummy.php: -------------------------------------------------------------------------------- 1 | stack = $stack; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/Serialisers/ObjectDeserialiserOKTest.php: -------------------------------------------------------------------------------- 1 | shouldReceive('resolveResourceSet')->withAnyArgs()->andReturn(null)->once(); 34 | 35 | $wrapper = m::mock(ProvidersWrapper::class); 36 | 37 | $foo = new CynicDeserialiser($meta, $wrapper); 38 | 39 | $payload = new ODataEntry(); 40 | $payload->resourceSetName = 'resourceSet'; 41 | 42 | $expected = 'Specified resource set could not be resolved'; 43 | $actual = null; 44 | 45 | try { 46 | $foo->processPayload($payload); 47 | } catch (\Exception $e) { 48 | $actual = $e->getMessage(); 49 | } 50 | $this->assertNotNull($actual); 51 | $this->assertEquals($expected, $actual); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/Serialisers/SerialiserTestBase.php: -------------------------------------------------------------------------------- 1 | makePartial()->shouldAllowMockingProtectedMethods(); 30 | $request->shouldReceive('getMethod')->andReturn($verb); 31 | $request->shouldReceive('getBaseUrl')->andReturn('http://localhost/'); 32 | //$request->shouldReceive('getQueryString')->andReturn(''); 33 | $request->shouldReceive('getHost')->andReturn('localhost'); 34 | $request->shouldReceive('isSecure')->andReturn(false); 35 | $request->shouldReceive('getPort')->andReturn(80); 36 | $request->shouldReceive('getRequestHeader') 37 | ->withArgs([ODataConstants::HTTPREQUEST_HEADER_DATA_SERVICE_VERSION])->andReturn('3.0'); 38 | 39 | return $request; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/Serialisers/TestDataService.php: -------------------------------------------------------------------------------- 1 | createProviders(); 15 | $this->getHost()->validateQueryParameters(); 16 | 17 | $uriProcessor = UriProcessor::process($this); 18 | return $uriProcessor; 19 | // we don't want to serialise the result here - we're intending to feed result description to serialiser(s) 20 | // under test 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/reusableEntityClass1.php: -------------------------------------------------------------------------------- 1 | name = $n; 15 | $this->type = $t; 16 | } 17 | 18 | public function __get($name) 19 | { 20 | return $this->{$name}; 21 | } 22 | 23 | public function __set($name, $value) 24 | { 25 | $this->{$name} = $value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/ObjectModel/reusableEntityClass3.php: -------------------------------------------------------------------------------- 1 | name = $n; 15 | $this->type = $t; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/OperationContext/SimpleOperationContextTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($foo->incomingRequest() instanceof SimpleRequestAdapter); 21 | $this->assertTrue($foo->outgoingResponse() instanceof OutgoingResponse); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/OperationContext/SimpleRequestAdapterTest.php: -------------------------------------------------------------------------------- 1 | getRawUrl(); 24 | $this->assertEquals($expected, $actual); 25 | } 26 | 27 | public function testGetRequestMethod() 28 | { 29 | // set up required superglobals 30 | $_SERVER['REQUEST_METHOD'] = 'PUT'; 31 | 32 | $foo = new SimpleRequestAdapter([]); 33 | $expected = HTTPRequestMethod::PUT(); 34 | $actual = $foo->getMethod(); 35 | $this->assertEquals($expected, $actual); 36 | } 37 | 38 | public function testGetQueryParms() 39 | { 40 | $expected = ['key' => 'secret']; 41 | $foo = new SimpleRequestAdapter($expected); 42 | $actual = $foo->getQueryParameters(); 43 | $this->assertEquals([$expected], $actual); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/OperationContext/Web/OutgoingResponseTest.php: -------------------------------------------------------------------------------- 1 | setETag('etag'); 19 | $this->assertEquals('etag', $foo->getETag()); 20 | } 21 | 22 | public function testAddHeader() 23 | { 24 | $foo = new OutgoingResponse(); 25 | $foo->addHeader('MO-DO', 'Eins Zwei Polizei'); 26 | $this->assertEquals('Eins Zwei Polizei', $foo->getHeaders()['MO-DO']); 27 | } 28 | 29 | public function testContentLengthRoundTrip() 30 | { 31 | $foo = new OutgoingResponse(); 32 | $foo->setContentLength('100'); 33 | $this->assertEquals('100', $foo->getHeaders()[ODataConstants::HTTPRESPONSE_HEADER_CONTENTLENGTH]); 34 | } 35 | 36 | public function testLastModifiedRoundTrip() 37 | { 38 | $foo = new OutgoingResponse(); 39 | $foo->setLastModified('100'); 40 | $this->assertEquals('100', $foo->getHeaders()[ODataConstants::HTTPRESPONSE_HEADER_LASTMODIFIED]); 41 | } 42 | 43 | public function testLocationRoundTrip() 44 | { 45 | $foo = new OutgoingResponse(); 46 | $foo->setLocation('100'); 47 | $this->assertEquals('100', $foo->getHeaders()[ODataConstants::HTTPRESPONSE_HEADER_LOCATION]); 48 | } 49 | 50 | public function testStatusDescriptionRoundTrip() 51 | { 52 | $foo = new OutgoingResponse(); 53 | $foo->setStatusDescription('100'); 54 | $this->assertEquals('100', $foo->getHeaders()[ODataConstants::HTTPRESPONSE_HEADER_STATUS_DESC]); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/OperationContext/Web/WebOperationContextTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($foo->incomingRequest() instanceof IHTTPRequest, get_class($foo->incomingRequest())); 21 | $this->assertTrue($foo->outgoingResponse() instanceof OutgoingResponse, get_class($foo->outgoingResponse())); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/PluralizerTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($expected, $actual); 28 | } 29 | 30 | public function testPluraliseUncountable() 31 | { 32 | $single = 'sheep'; 33 | 34 | $expected = 'sheep'; 35 | 36 | $actual = Pluralizer::plural($single, 2); 37 | $this->assertEquals($expected, $actual); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Providers/Metadata/ResourceAssociationTypeEndTest.php: -------------------------------------------------------------------------------- 1 | getMessage(); 27 | } 28 | $this->assertEquals($expected, $actual); 29 | } 30 | 31 | public function testIsBelongsToWithNullResourceType() 32 | { 33 | $type = m::mock(ResourceEntityType::class); 34 | $type->shouldReceive('getFullName')->andReturn('Northwind.Customer', 'Northwind.Order'); 35 | $from = m::mock(ResourceProperty::class); 36 | 37 | $foo = new ResourceAssociationTypeEnd('name', $type, null, $from); 38 | 39 | $result = $foo->isBelongsTo($type, null); 40 | $this->assertFalse($result); 41 | } 42 | 43 | public function testIsBelongsToWithNullMismatchOnResourceTypes() 44 | { 45 | $type = m::mock(ResourceEntityType::class); 46 | $type->shouldReceive('getFullName')->andReturn('Northwind.Customer', 'Northwind.Order'); 47 | $from = m::mock(ResourceProperty::class); 48 | 49 | $foo = new ResourceAssociationTypeEnd('name', $type, null, $from); 50 | $result = $foo->isBelongsTo($type, $from); 51 | $this->assertFalse($result); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Providers/Metadata/ResourceStreamInfoTest.php: -------------------------------------------------------------------------------- 1 | setCustomState($object); 19 | $result = $foo->getCustomState(); 20 | $this->assertEquals('foo', $result->name); 21 | $this->assertEquals('bar', $result->type); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Providers/Query/QueryResultTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($expected, $actual, strval($id)); 25 | } 26 | 27 | public function provider() 28 | { 29 | return [ 30 | //count //top //skip //expected 31 | [101, 0, null, null, 0], 32 | [102, 1, null, null, 1], 33 | [103, 10, 1, null, 1], 34 | [104, 0, 1, null, 0], 35 | [105, 0, null, 1, 0], 36 | [105, 0, 1, 1, 0], 37 | [106, 10, 5, 5, 5], 38 | [107, 10, 5, 7, 3], 39 | [107, 10, 15, 7, 3], 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Readers/Atom/LinkProcessorTest.php: -------------------------------------------------------------------------------- 1 | handleChildComplete($obj); 31 | 32 | $result = $foo->getObjetModelObject()->getExpandedResult(); 33 | $this->assertTrue($result->getFeed() instanceof ODataFeed); 34 | $this->assertNull($result->getEntry()); 35 | } 36 | 37 | public function testConstructorWithEditMediaRelation() 38 | { 39 | $parms = 40 | [strtoupper(ODataConstants::ATOM_LINK_RELATION_ATTRIBUTE_NAME) => 41 | ODataConstants::ATOM_EDIT_MEDIA_RELATION_ATTRIBUTE_VALUE]; 42 | 43 | $foo = new LinkProcessor($parms); 44 | $result = $foo->getObjetModelObject(); 45 | $this->assertTrue($result instanceof ODataMediaLink); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Readers/Atom/ProcessPropertyTest.php: -------------------------------------------------------------------------------- 1 | handleChildComplete($model); 28 | $this->assertTrue(true); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/TestCase.php: -------------------------------------------------------------------------------- 1 | reset(); 23 | $bar = new SimpleMetadataProvider('Data', 'Data'); 24 | unset($bar); 25 | DateTime::setTimeProvider([new Carbon(), 'now']); 26 | } 27 | 28 | public function tearDown() 29 | { 30 | \Mockery::close(); 31 | DateTime::setTimeProvider(null); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/ExpandProjectionParser/ExpandedProjectionNodeTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($skipCount, $foo->getSkipCount()); 27 | $this->assertEquals($takeCount, $foo->getTakeCount()); 28 | $this->assertEquals($maxResultCount, $foo->getMaxResultCount()); 29 | } 30 | 31 | public function testSelectionFoundRoundTripTrue() 32 | { 33 | $foo = m::mock(ExpandedProjectionNode::class)->makePartial(); 34 | $foo->setSelectionFound(true); 35 | $this->assertTrue($foo->isSelectionFound()); 36 | } 37 | 38 | public function testSelectionFoundRoundTripFalse() 39 | { 40 | $foo = m::mock(ExpandedProjectionNode::class)->makePartial(); 41 | $foo->setSelectionFound(false); 42 | $this->assertFalse($foo->isSelectionFound()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/ExpressionParser/DummyExpressionParser.php: -------------------------------------------------------------------------------- 1 | lexer = $lexer; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/ArithmeticExpressionTest.php: -------------------------------------------------------------------------------- 1 | shouldReceive('free')->andReturnNull()->once(); 22 | $expr2 = m::mock(AbstractExpression::class); 23 | $expr2->shouldReceive('free')->andReturnNull()->once(); 24 | $expression = m::mock(ExpressionType::class); 25 | $iType = m::mock(IType::class); 26 | 27 | $foo = new ArithmeticExpression($expr1, $expr2, $expression, $iType); 28 | $this->assertNotNull($foo->getLeft()); 29 | $this->assertNotNull($foo->getRight()); 30 | $foo->free(); 31 | $this->assertNull($foo->getLeft()); 32 | $this->assertNull($foo->getRight()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/ConstantExpressionTest.php: -------------------------------------------------------------------------------- 1 | assertNotNull($foo->getValue()); 26 | $foo->free(); 27 | $this->assertNull($foo->getValue()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/FunctionCallExpressionTest.php: -------------------------------------------------------------------------------- 1 | shouldReceive('free')->andReturnNull()->once(); 21 | $expr2 = m::mock(AbstractExpression::class); 22 | $expr2->shouldReceive('free')->andReturnNull()->once(); 23 | 24 | $foo = new FunctionCallExpression($descript, [$expr1, $expr2]); 25 | $this->assertEquals(2, count($foo->getParamExpressions())); 26 | $foo->free(); 27 | $this->assertEquals(0, count($foo->getParamExpressions())); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/PropertyAccessExpressionTest.php: -------------------------------------------------------------------------------- 1 | shouldReceive('free')->andReturnNull()->once(); 24 | $parent->shouldReceive('setChild')->andReturnNull()->once(); 25 | $child = m::mock(PropertyAccessExpression::class); 26 | $child->shouldReceive('free')->andReturnNull()->once(); 27 | 28 | $iType = m::mock(IType::class); 29 | $rType = m::mock(ResourceType::class); 30 | $rType->shouldReceive('getResourceTypeKind')->andReturn(ResourceTypeKind::PRIMITIVE()); 31 | $rType->shouldReceive('getInstanceType')->andReturn($iType); 32 | 33 | $prop = m::mock(ResourceProperty::class); 34 | $prop->shouldReceive('getResourceType')->andReturn($rType); 35 | 36 | $foo = new PropertyAccessExpression($prop, $parent); 37 | $foo->setChild($child); 38 | $this->assertNotNull($foo->getParent()); 39 | $this->assertNotNull($foo->getChild()); 40 | $foo->free(); 41 | $this->assertNull($foo->getParent()); 42 | $this->assertNull($foo->getChild()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/ExpressionParser/Expressions/UnaryExpressionTest.php: -------------------------------------------------------------------------------- 1 | shouldReceive('free')->andReturnNull()->once(); 23 | $expression = m::mock(ExpressionType::class); 24 | $iType = m::mock(IType::class); 25 | 26 | $foo = new UnaryExpression($expr1, $expression, $iType); 27 | $this->assertNotNull($foo->getChild()); 28 | $foo->free(); 29 | $this->assertNull($foo->getChild()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/OrderByParser/OrderByInfoTest.php: -------------------------------------------------------------------------------- 1 | getMessage(); 23 | } 24 | $this->assertNotNull($actual); 25 | $this->assertEquals($expected, $actual); 26 | } 27 | 28 | public function testCreateWithEmptyArrayNavProperties() 29 | { 30 | $expected = 'The argument navigationPropertiesUsedInTheOrderByClause should be' 31 | . ' either null or a non-empty array'; 32 | $actual = null; 33 | 34 | try { 35 | new OrderByInfo(['abc'], []); 36 | } catch (\InvalidArgumentException $e) { 37 | $actual = $e->getMessage(); 38 | } 39 | $this->assertNotNull($actual); 40 | $this->assertEquals($expected, $actual); 41 | } 42 | 43 | public function testSetIsSortedRoundTrip() 44 | { 45 | $foo = new OrderByInfo(['abc'], null); 46 | 47 | $foo->setSorted(false); 48 | $this->assertTrue($foo->requireInternalSorting()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/OrderByParser/OrderByLeafNodeTest.php: -------------------------------------------------------------------------------- 1 | shouldReceive('getResourceType')->andReturn($rType); 27 | $isAscending = true; 28 | 29 | $foo = new OrderByLeafNode($propName, $rProp, $isAscending); 30 | 31 | $this->assertTrue(null !== $foo->getResourceType()); 32 | $this->assertTrue($foo->getResourceType() instanceof ResourceType); 33 | } 34 | 35 | public function testBuildComparisonFunctionFromEmptyArray() 36 | { 37 | $expected = 'There should be at least one ancestor for building the sort function'; 38 | $actual = null; 39 | 40 | $propName = 'property'; 41 | $rType = m::mock(ResourceEntityType::class); 42 | $rProp = m::mock(ResourceProperty::class); 43 | $rProp->shouldReceive('getResourceType')->andReturn($rType); 44 | $isAscending = true; 45 | 46 | $foo = new OrderByLeafNode($propName, $rProp, $isAscending); 47 | 48 | try { 49 | $foo->buildComparisonFunction([]); 50 | } catch (\InvalidArgumentException $e) { 51 | $actual = $e->getMessage(); 52 | } 53 | $this->assertNotNull($actual); 54 | $this->assertEquals($expected, $actual); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/OrderByParser/OrderByPathSegmentTest.php: -------------------------------------------------------------------------------- 1 | getMessage(); 26 | } 27 | $this->assertNotNull($actual); 28 | $this->assertEquals($expected, $actual); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/QueryProcessor/SkipTokenParser/SkipTokenInfoTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($foo->getOrderByInfo() instanceof OrderByInfo); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/ResourcePathProcessor/SegmentParser/SegmentDescriptorTest.php: -------------------------------------------------------------------------------- 1 | assertFalse($foo->hasKeyValues()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/UriProcessor/UriProcessorDummy.php: -------------------------------------------------------------------------------- 1 | writeLine(); 21 | $this->assertSame($writer, $result); 22 | $this->assertEquals(PHP_EOL, $writer->getResult()); 23 | } 24 | 25 | public function testWrite() 26 | { 27 | $writer = new IndentedTextWriter('', PHP_EOL, true); 28 | 29 | $result = $writer->writeValue(' doggy '); 30 | 31 | $this->assertSame($writer, $result); 32 | $this->assertEquals(' doggy ', $writer->getResult()); 33 | } 34 | 35 | public function testWriteTrimmed() 36 | { 37 | $writer = new IndentedTextWriter('', PHP_EOL, true); 38 | 39 | $result = $writer->writeTrimmed(' doggy '); 40 | 41 | $this->assertSame($writer, $result); 42 | $this->assertEquals('doggy', $writer->getResult()); 43 | } 44 | 45 | public function testWriteIndents() 46 | { 47 | $writer = new IndentedTextWriter('', PHP_EOL, true); 48 | 49 | $result = $writer->increaseIndent(); 50 | $this->assertSame($writer, $result); 51 | 52 | $writer->writeValue('indented1x'); 53 | $writer->writeLine(); 54 | 55 | $writer->increaseIndent(); 56 | $writer->writeValue('indented2x'); 57 | $writer->writeLine(); 58 | 59 | $result = $writer->decreaseIndent(); 60 | $this->assertSame($writer, $result); 61 | $writer->writeValue('indented1x'); 62 | $writer->writeTrimmed(' trimmed '); 63 | $writer->writeLine(); 64 | 65 | $writer->decreaseIndent(); 66 | $writer->decreaseIndent(); 67 | $writer->decreaseIndent(); 68 | $writer->decreaseIndent(); 69 | $writer->decreaseIndent(); 70 | $writer->decreaseIndent(); 71 | $writer->decreaseIndent(); 72 | 73 | $writer->writeValue('indented0x'); 74 | $expected = 'indented1x' . PHP_EOL . ' indented2x' . PHP_EOL . ' indented1xtrimmed' . PHP_EOL . 'indented0x'; 75 | 76 | $this->assertEquals($expected, $writer->getResult()); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Writers/Json/WriterFencePostTest.php: -------------------------------------------------------------------------------- 1 | makePartial(); 49 | 50 | $result = $foo->write($payload); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/UnitTests/POData/Writers/ODataWriterRegistryTest.php: -------------------------------------------------------------------------------- 1 | assertNull($registry->getWriter(Version::v1(), MimeTypes::MIME_APPLICATION_JSON)); 21 | } 22 | 23 | public function testRegister() 24 | { 25 | $writer1 = m::mock(IODataWriter::class)->makePartial(); 26 | $writer1->shouldReceive('canHandle')->andReturn(false); 27 | $writer2 = m::mock(IODataWriter::class)->makePartial(); 28 | $writer2->shouldReceive('canHandle')->withArgs([Version::v2(), MimeTypes::MIME_APPLICATION_ATOM]) 29 | ->andReturn(true); 30 | $writer2->shouldReceive('canHandle')->andReturn(false); 31 | 32 | $registry = new ODataWriterRegistry(); 33 | 34 | $registry->register($writer1); 35 | $registry->register($writer2); 36 | 37 | $this->assertEquals($writer2, $registry->getWriter(Version::v2(), MimeTypes::MIME_APPLICATION_ATOM)); 38 | 39 | $this->assertNull($registry->getWriter(Version::v1(), MimeTypes::MIME_APPLICATION_ATOM)); 40 | 41 | //now clear it, should be no matches 42 | $registry->reset(); 43 | $this->assertNull($registry->getWriter(Version::v2(), MimeTypes::MIME_APPLICATION_ATOM)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |