Initial Commit
This commit is contained in:
commit
9b588562da
27 changed files with 1668 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
build/
|
46
.gitlab-ci.yml
Normal file
46
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,46 @@
|
|||
image: php:8.1
|
||||
|
||||
before_script:
|
||||
# Install some stuff that the image doesn't come with
|
||||
- apt update -yqq
|
||||
- apt install git libpq-dev libzip-dev zip make wget gnupg -yqq
|
||||
|
||||
# Install phive
|
||||
- wget -O phive.phar https://phar.io/releases/phive.phar
|
||||
- wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc
|
||||
- gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79
|
||||
- gpg --verify phive.phar.asc phive.phar
|
||||
- chmod +x phive.phar
|
||||
- mv phive.phar /usr/local/bin/phive
|
||||
|
||||
# Install phab
|
||||
- phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C
|
||||
|
||||
# Install the latest version of ncc (Nosial Code Compiler)
|
||||
- git clone https://git.n64.cc/nosial/ncc.git
|
||||
- cd ncc
|
||||
- make redist
|
||||
- php build/src/INSTALL --auto --install-composer
|
||||
- cd .. && rm -rf ncc
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- ncc build --config release --log-level debug
|
||||
artifacts:
|
||||
paths:
|
||||
- build/
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
|
||||
release:
|
||||
stage: deploy
|
||||
script:
|
||||
- ncc build --config release --log-level debug
|
||||
- >
|
||||
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/release/net.nosial.rsslib.ncc "$CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/generic/net.nosial.rsslib.ncc/$CI_COMMIT_REF_NAME/net.nosial.rsslib.ncc"
|
||||
artifacts:
|
||||
paths:
|
||||
- build/
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
11
.idea/RssLib.iml
generated
Normal file
11
.idea/RssLib.iml
generated
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
29
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
29
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
@ -0,0 +1,29 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="IncorrectHttpHeaderInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="customHeaders">
|
||||
<set>
|
||||
<option value="Subject" />
|
||||
<option value="Reply-To" />
|
||||
<option value="X-JSON-Schema" />
|
||||
<option value="X-JSON-Type" />
|
||||
<option value="X-JSON-Path" />
|
||||
<option value="X-Java-Type" />
|
||||
<option value="X-Region-Id" />
|
||||
<option value="X-GraphQL-Variables" />
|
||||
<option value="X-SSH-Private-Key" />
|
||||
<option value="X-Temperature" />
|
||||
<option value="X-Model" />
|
||||
<option value="X-OPENAI-API-KEY" />
|
||||
<option value="X-Args-0" />
|
||||
<option value="X-Args-1" />
|
||||
<option value="X-Args-2" />
|
||||
<option value="X-Args-3" />
|
||||
<option value="X-Args-4" />
|
||||
<option value="X-Args-5" />
|
||||
</set>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/RssLib.iml" filepath="$PROJECT_DIR$/.idea/RssLib.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
20
.idea/php.xml
generated
Normal file
20
.idea/php.xml
generated
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MessDetectorOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCSFixerOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
</project>
|
10
.idea/runConfigurations/Build.xml
generated
Normal file
10
.idea/runConfigurations/Build.xml
generated
Normal file
|
@ -0,0 +1,10 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Build" type="MAKEFILE_TARGET_RUN_CONFIGURATION" factoryName="Makefile" activateToolWindowBeforeRun="false">
|
||||
<makefile filename="$PROJECT_DIR$/Makefile" target="build" workingDirectory="" arguments="">
|
||||
<envs />
|
||||
</makefile>
|
||||
<method v="2">
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Clean" run_configuration_type="MAKEFILE_TARGET_RUN_CONFIGURATION" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
8
.idea/runConfigurations/Clean.xml
generated
Normal file
8
.idea/runConfigurations/Clean.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Clean" type="MAKEFILE_TARGET_RUN_CONFIGURATION" factoryName="Makefile" activateToolWindowBeforeRun="false">
|
||||
<makefile filename="$PROJECT_DIR$/Makefile" target="clean" workingDirectory="" arguments="">
|
||||
<envs />
|
||||
</makefile>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
10
.idea/runConfigurations/Install.xml
generated
Normal file
10
.idea/runConfigurations/Install.xml
generated
Normal file
|
@ -0,0 +1,10 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Install" type="MAKEFILE_TARGET_RUN_CONFIGURATION" factoryName="Makefile" activateToolWindowBeforeRun="false">
|
||||
<makefile filename="$PROJECT_DIR$/Makefile" target="install" workingDirectory="" arguments="">
|
||||
<envs />
|
||||
</makefile>
|
||||
<method v="2">
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Build" run_configuration_type="MAKEFILE_TARGET_RUN_CONFIGURATION" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
14
LICENSE
Normal file
14
LICENSE
Normal file
|
@ -0,0 +1,14 @@
|
|||
Copyright 2022-2023 Nosial All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
8
Makefile
Normal file
8
Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
build:
|
||||
ncc build --config="release" --log-level debug
|
||||
|
||||
install:
|
||||
sudo ncc package install --package="build/release/net.nosial.rsslib.ncc" --skip-dependencies --reinstall -y --log-level debug
|
||||
|
||||
clean:
|
||||
rm -rf build
|
82
README.md
Normal file
82
README.md
Normal file
|
@ -0,0 +1,82 @@
|
|||
# RssLib
|
||||
|
||||
RssLib is a library used to parse RSS feeds and return the data in a usable format.
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [RssLib](#rsslib)
|
||||
* [Table of contents](#table-of-contents)
|
||||
* [Installation](#installation)
|
||||
* [Compile from source](#compile-from-source)
|
||||
* [Requirements](#requirements)
|
||||
* [Documentation](#documentation)
|
||||
* [License](#license)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
The library can be installed using ncc:
|
||||
|
||||
```bash
|
||||
ncc install -p "nosial/libs.rss=latest@n64"
|
||||
```
|
||||
|
||||
or by adding the following to your project.json file under the `build.dependencies` section:
|
||||
```json
|
||||
{
|
||||
"name": "net.nosial.rsslib",
|
||||
"version": "latest",
|
||||
"source_type": "remote",
|
||||
"source": "nosial/libs.rsslib=latest@n64"
|
||||
}
|
||||
```
|
||||
|
||||
If you don't have the n64 source configured, you can add it by running the following command:
|
||||
```bash
|
||||
ncc source add --name n64 --type gitlab --host git.n64.cc
|
||||
```
|
||||
|
||||
## Compile from source
|
||||
|
||||
To compile the library from source, you need to have [ncc](https://git.n64.cc/nosial/ncc) installed, then run the
|
||||
following command:
|
||||
|
||||
```bash
|
||||
ncc build
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
The library requires PHP 8.0 or higher.
|
||||
|
||||
## Documentation
|
||||
|
||||
The library is designed to be used as a dependency in other projects, and as such, does not have a command-line
|
||||
interface. The library is designed to be used as follows:
|
||||
|
||||
```php
|
||||
try
|
||||
{
|
||||
$feed = \RssLib\RssLib::getFeed('https://rss.nytimes.com/services/xml/rss/nyt/World.xml');
|
||||
}
|
||||
catch(\RssLib\Exceptions\RssFeedException $e)
|
||||
{
|
||||
echo $e->getMessage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print("Title: {$feed->getTitle()}\n");
|
||||
print("Description: {$feed->getDescription()}\n");
|
||||
foreach($feed->getItems() as $item)
|
||||
{
|
||||
print("Item: {$item->getTitle()}\n");
|
||||
print("Description: {$item->getDescription()}\n");
|
||||
print("Link: {$item->getLink()}\n");
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the MIT License. See `LICENSE` for more information.
|
29
project.json
Normal file
29
project.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"project": {
|
||||
"compiler": {
|
||||
"extension": "php",
|
||||
"minimum_version": "8.0",
|
||||
"maximum_version": "8.2"
|
||||
},
|
||||
"options": []
|
||||
},
|
||||
"assembly": {
|
||||
"name": "RssLib",
|
||||
"package": "net.nosial.rsslib",
|
||||
"description": "A library used to parse RSS feeds",
|
||||
"company": "Nosial",
|
||||
"copyright": "Copyright (c) 2022-2023 Nosial",
|
||||
"version": "1.0.0",
|
||||
"uuid": "f24416e8-39f0-11ee-8dcf-f362baa8b68c"
|
||||
},
|
||||
"build": {
|
||||
"source_path": "src",
|
||||
"default_configuration": "release",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "release",
|
||||
"output_path": "build/release"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
85
src/RssLib/Classes/Utilities.php
Normal file
85
src/RssLib/Classes/Utilities.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace RssLib\Classes;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use SimpleXMLElement;
|
||||
|
||||
class Utilities
|
||||
{
|
||||
/**
|
||||
* Attempts to parse a string into a timestamp
|
||||
*
|
||||
* @param string $input
|
||||
* @return int
|
||||
*/
|
||||
public static function parseTimestamp(string $input): int
|
||||
{
|
||||
$timestamp = strtotime($input);
|
||||
|
||||
if($timestamp === false)
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Invalid timestamp %s', $input));
|
||||
}
|
||||
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a SimpleXMLElement to an array representation
|
||||
*
|
||||
* @param SimpleXMLElement $element
|
||||
* @return array
|
||||
* @noinspection UnknownInspectionInspection
|
||||
*/
|
||||
public static function xmlToArray(SimpleXMLElement $element): array
|
||||
{
|
||||
$array = [];
|
||||
if ($element->attributes())
|
||||
{
|
||||
foreach ($element->attributes() as $name => $value)
|
||||
{
|
||||
$array[$element->getName() . '_' . $name] = (string)$value;
|
||||
}
|
||||
if (trim((string)$element) !== '')
|
||||
{
|
||||
$array[$element->getName()] = trim((string)$element);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle child elements
|
||||
$items = [];
|
||||
foreach ($element->children() as $child)
|
||||
{
|
||||
$value = ($child->count() > 0 || $child->attributes()) ? self::xmlToArray($child) : (string)$child;
|
||||
|
||||
if ($child->getName() === 'item')
|
||||
{
|
||||
$items[] = $value;
|
||||
}
|
||||
else if (isset($array[$child->getName()]))
|
||||
{
|
||||
if (!is_array($array[$child->getName()]))
|
||||
{
|
||||
$array[$child->getName()] = [$array[$child->getName()]];
|
||||
}
|
||||
|
||||
/** @noinspection UnsupportedStringOffsetOperationsInspection */
|
||||
$array[$child->getName()][] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$array[$child->getName()] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($items))
|
||||
{
|
||||
$array['item'] = $items;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
}
|
10
src/RssLib/Exceptions/RssFeedException.php
Normal file
10
src/RssLib/Exceptions/RssFeedException.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace RssLib\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class RssFeedException extends Exception
|
||||
{
|
||||
// This class can be empty :)
|
||||
}
|
21
src/RssLib/Interfaces/SerializableObjectInterface.php
Normal file
21
src/RssLib/Interfaces/SerializableObjectInterface.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace RssLib\Interfaces;
|
||||
|
||||
interface SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array;
|
||||
|
||||
/**
|
||||
* Constructs an object from an array representation
|
||||
*
|
||||
* @param array $array
|
||||
* @return SerializableObjectInterface
|
||||
*/
|
||||
public static function fromArray(array $array): SerializableObjectInterface;
|
||||
}
|
400
src/RssLib/Objects/RssChannel.php
Normal file
400
src/RssLib/Objects/RssChannel.php
Normal file
|
@ -0,0 +1,400 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace RssLib\Objects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RssLib\Classes\Utilities;
|
||||
use RssLib\Interfaces\SerializableObjectInterface;
|
||||
use RssLib\Objects\RssChannel\Image;
|
||||
use RssLib\Objects\RssChannel\TextInput;
|
||||
|
||||
class RssChannel implements SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $link;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $language;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $copyright;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $managing_editor;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $web_master;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $publish_date;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $last_build_date;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
private $categories;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $generator;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $docs;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $cloud;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $ttl;
|
||||
|
||||
/**
|
||||
* @var Image|null
|
||||
*/
|
||||
private $image;
|
||||
|
||||
/**
|
||||
* @var TextInput|null
|
||||
*/
|
||||
private $text_input;
|
||||
|
||||
/**
|
||||
* @var RssItem[]
|
||||
*/
|
||||
private $items;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach(['title', 'link', 'description'] as $key)
|
||||
{
|
||||
if(!array_key_exists($key, $data))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Missing required key %s for channel', $key));
|
||||
}
|
||||
}
|
||||
|
||||
$this->title = (string)$data['title'];
|
||||
$this->link = (string)$data['link'];
|
||||
$this->description = (string)$data['description'];
|
||||
|
||||
if(array_key_exists('language', $data))
|
||||
{
|
||||
$this->language = (string)$data['language'];
|
||||
}
|
||||
|
||||
if(array_key_exists('copyright', $data))
|
||||
{
|
||||
$this->copyright = (string)$data['copyright'];
|
||||
}
|
||||
|
||||
if(array_key_exists('managingEditor', $data))
|
||||
{
|
||||
$this->managing_editor = (string)$data['managingEditor'];
|
||||
}
|
||||
|
||||
if(array_key_exists('webMaster', $data))
|
||||
{
|
||||
$this->web_master = (string)$data['webMaster'];
|
||||
}
|
||||
|
||||
if(array_key_exists('pubDate', $data))
|
||||
{
|
||||
$this->publish_date = Utilities::parseTimestamp((string)$data['pubDate']);
|
||||
}
|
||||
|
||||
if(array_key_exists('lastBuildDate', $data))
|
||||
{
|
||||
$this->last_build_date = Utilities::parseTimestamp((string)$data['lastBuildDate']);
|
||||
}
|
||||
|
||||
if(array_key_exists('category', $data))
|
||||
{
|
||||
$this->categories = (array)$data['category'];
|
||||
}
|
||||
|
||||
if(array_key_exists('generator', $data))
|
||||
{
|
||||
$this->generator = (string)$data['generator'];
|
||||
}
|
||||
|
||||
if(array_key_exists('docs', $data))
|
||||
{
|
||||
$this->docs = (string)$data['docs'];
|
||||
}
|
||||
|
||||
if(array_key_exists('cloud', $data))
|
||||
{
|
||||
$this->cloud = (string)$data['cloud'];
|
||||
}
|
||||
|
||||
if(array_key_exists('ttl', $data))
|
||||
{
|
||||
$this->ttl = (int)$data['ttl'];
|
||||
}
|
||||
|
||||
if(array_key_exists('image', $data))
|
||||
{
|
||||
$this->image = new Image($data['image']);
|
||||
}
|
||||
|
||||
if(array_key_exists('textInput', $data))
|
||||
{
|
||||
$this->text_input = new TextInput($data['textInput']);
|
||||
}
|
||||
|
||||
$this->items = [];
|
||||
if(array_key_exists('item', $data))
|
||||
{
|
||||
foreach($data['item'] as $item)
|
||||
{
|
||||
$this->items[] = new RssItem($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the channel. It's how people refer to your service. If you have an HTML website that contains
|
||||
* the same information as your RSS file, the title of your channel should be the same as the title of your
|
||||
* website.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL to the HTML website corresponding to the channel.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLink(): string
|
||||
{
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Phrase or sentence describing the channel.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The language the channel is written in
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLanguage(): ?string
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copyright notice for content in the channel.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCopyright(): ?string
|
||||
{
|
||||
return $this->copyright;
|
||||
}
|
||||
|
||||
/**
|
||||
* Email address for person responsible for editorial content.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getManagingEditor(): ?string
|
||||
{
|
||||
return $this->managing_editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Email address for person responsible for technical issues relating to channel.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getWebMaster(): ?string
|
||||
{
|
||||
return $this->web_master;
|
||||
}
|
||||
|
||||
/**
|
||||
* The publication date for the content in the channel
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getPublishDate(): ?int
|
||||
{
|
||||
return $this->publish_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* The last time the content of the channel changed.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getLastBuildDate(): ?int
|
||||
{
|
||||
return $this->last_build_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify one or more categories that the channel belongs to
|
||||
*
|
||||
* @return string[]|null
|
||||
*/
|
||||
public function getCategories(): ?array
|
||||
{
|
||||
return $this->categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* A string indicating the program used to generate the channel.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getGenerator(): ?string
|
||||
{
|
||||
return $this->generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* A URL that points to the documentation for the format used in the RSS file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDocs(): ?string
|
||||
{
|
||||
return $this->docs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows processes to register with a cloud to be notified of updates to the channel, implementing a
|
||||
* lightweight publish-subscribe protocol for RSS feeds
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCloud(): ?string
|
||||
{
|
||||
return $this->cloud;
|
||||
}
|
||||
|
||||
/**
|
||||
* ttl stands for time to live. It's a number of minutes that indicates how long a channel can be cached before
|
||||
* refreshing from the source
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getTtl(): ?int
|
||||
{
|
||||
return $this->ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a GIF, JPEG or PNG image that can be displayed with the channel
|
||||
*
|
||||
* @return Image|null
|
||||
*/
|
||||
public function getImage(): ?Image
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a text input box that can be displayed with the channel. More info
|
||||
*
|
||||
* @return TextInput|null
|
||||
*/
|
||||
public function getTextInput(): ?TextInput
|
||||
{
|
||||
return $this->text_input;
|
||||
}
|
||||
|
||||
/**
|
||||
* The items in the channel
|
||||
*
|
||||
* @return RssItem[]
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'link' => $this->link,
|
||||
'description' => $this->description,
|
||||
'language' => $this->language,
|
||||
'managingEditor' => $this->managing_editor,
|
||||
'webMaster' => $this->web_master,
|
||||
'pubDate' => $this->publish_date,
|
||||
'lastBuildDate' => $this->last_build_date,
|
||||
'category' => $this->categories,
|
||||
'generator' => $this->generator,
|
||||
'docs' => $this->docs,
|
||||
'cloud' => $this->cloud,
|
||||
'ttl' => $this->ttl,
|
||||
'image' => ($this->image) ? $this->image->toArray() : null,
|
||||
'textInput' => ($this->text_input) ? $this->text_input->toArray() : null,
|
||||
'item' => array_map(static function(RssItem $item) {
|
||||
return $item->toArray();
|
||||
}, $this->items)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function fromArray(array $array): SerializableObjectInterface
|
||||
{
|
||||
return new self($array);
|
||||
}
|
||||
}
|
159
src/RssLib/Objects/RssChannel/Image.php
Normal file
159
src/RssLib/Objects/RssChannel/Image.php
Normal file
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace RssLib\Objects\RssChannel;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RssLib\Interfaces\SerializableObjectInterface;
|
||||
|
||||
class Image implements SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $link;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $width;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $height;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach(['url', 'title', 'link'] as $key)
|
||||
{
|
||||
if(!array_key_exists($key, $data))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Missing required key %s for image', $key));
|
||||
}
|
||||
}
|
||||
|
||||
$this->url = (string)$data['url'];
|
||||
$this->title = (string)$data['title'];
|
||||
$this->link = (string)$data['link'];
|
||||
|
||||
if(array_key_exists('width', $data))
|
||||
{
|
||||
$this->width = (int)$data['width'];
|
||||
}
|
||||
|
||||
if(array_key_exists('height', $data))
|
||||
{
|
||||
$this->height = (int)$data['height'];
|
||||
}
|
||||
|
||||
if(array_key_exists('description', $data))
|
||||
{
|
||||
$this->description = (string)$data['description'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* the URL of a GIF, JPEG or PNG image that represents the channel.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* describes the image, it's used in the ALT attribute of the HTML <img> tag when the channel is rendered in HTML.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* the URL of the site, when the channel is rendered, the image is a link to the site.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLink(): string
|
||||
{
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. The width of the image in pixels
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getWidth(): ?int
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. The height of the image in pixels
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getHeight(): ?int
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. Specifies the text in the HTML TITLE attribute of the link around the image
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'url' => $this->url,
|
||||
'title' => $this->title,
|
||||
'link' => $this->link,
|
||||
'width' => $this->width,
|
||||
'height' => $this->height,
|
||||
'description' => $this->description
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function fromArray(array $array): Image
|
||||
{
|
||||
return new self($array);
|
||||
}
|
||||
}
|
113
src/RssLib/Objects/RssChannel/TextInput.php
Normal file
113
src/RssLib/Objects/RssChannel/TextInput.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace RssLib\Objects\RssChannel;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RssLib\Interfaces\SerializableObjectInterface;
|
||||
|
||||
class TextInput implements SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $link;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach(['title', 'description', 'name', 'link'] as $key)
|
||||
{
|
||||
if(!array_key_exists($key, $data))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Missing required key %s for text input', $key));
|
||||
}
|
||||
}
|
||||
|
||||
$this->title = (string)$data['title'];
|
||||
$this->description = (string)$data['description'];
|
||||
$this->name = (string)$data['name'];
|
||||
$this->link = (string)$data['link'];
|
||||
}
|
||||
|
||||
/**
|
||||
* The label of the Submit button in the text input area.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explains the text input area.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the text object in the text input area.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the CGI script that processes text input requests.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLink(): string
|
||||
{
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'description' => $this->description,
|
||||
'name' => $this->name,
|
||||
'link' => $this->link
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function fromArray(array $array): TextInput
|
||||
{
|
||||
return new self($array);
|
||||
}
|
||||
}
|
96
src/RssLib/Objects/RssFeed/Enclosure.php
Normal file
96
src/RssLib/Objects/RssFeed/Enclosure.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace RssLib\Objects\RssFeed;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RssLib\Interfaces\SerializableObjectInterface;
|
||||
|
||||
class Enclosure implements SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $length;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach(['enclosure_url', 'enclosure_length', 'enclosure_type'] as $key)
|
||||
{
|
||||
if(!array_key_exists($key, $data))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Missing required key %s for enclosure', $key));
|
||||
}
|
||||
}
|
||||
|
||||
$this->url = (string)$data['enclosure_url'];
|
||||
$this->length = (int)$data['enclosure_length'];
|
||||
$this->type = (string)$data['enclosure_type'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Required. Defines the URL to the media file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required. Defines the length of the media file in bytes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLength(): string
|
||||
{
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required. Defines the MIME type of the media file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'enclosure_url' => $this->url,
|
||||
'enclosure_length' => $this->length,
|
||||
'enclosure_type' => $this->type
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function fromArray(array $array): Enclosure
|
||||
{
|
||||
return new self($array);
|
||||
}
|
||||
}
|
84
src/RssLib/Objects/RssFeed/Guid.php
Normal file
84
src/RssLib/Objects/RssFeed/Guid.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace RssLib\Objects\RssFeed;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RssLib\Interfaces\SerializableObjectInterface;
|
||||
|
||||
class Guid implements SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $guid;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $is_permalink;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
if(!array_key_exists('guid', $data))
|
||||
{
|
||||
throw new InvalidArgumentException('Missing required key guid for guid');
|
||||
}
|
||||
|
||||
$this->guid = (string)$data['guid'];
|
||||
|
||||
if(array_key_exists('guid_isPermalink', $data))
|
||||
{
|
||||
$this->is_permalink = (bool)$data['guid_isPermalink'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->is_permalink = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the guid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGuid(): string
|
||||
{
|
||||
return $this->guid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns True if the guid is a permalink, False otherwise
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPermalink(): bool
|
||||
{
|
||||
return $this->is_permalink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'guid' => $this->guid,
|
||||
'guid_isPermalink' => $this->is_permalink
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function fromArray(array $array): Guid
|
||||
{
|
||||
return new Guid($array);
|
||||
}
|
||||
}
|
79
src/RssLib/Objects/RssFeed/Source.php
Normal file
79
src/RssLib/Objects/RssFeed/Source.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace RssLib\Objects\RssFeed;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RssLib\Interfaces\SerializableObjectInterface;
|
||||
|
||||
class Source implements SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $source;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach(['source', 'source_url'] as $key)
|
||||
{
|
||||
if(!array_key_exists($key, $data))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Missing required key %s for source', $key));
|
||||
}
|
||||
}
|
||||
|
||||
$this->url = (string)$data['source_url'];
|
||||
$this->source = (string)$data['source'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSource(): string
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'source_url' => $this->url,
|
||||
'source' => $this->source
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function fromArray(array $array): Source
|
||||
{
|
||||
return new static($array);
|
||||
}
|
||||
}
|
253
src/RssLib/Objects/RssItem.php
Normal file
253
src/RssLib/Objects/RssItem.php
Normal file
|
@ -0,0 +1,253 @@
|
|||
<?php /** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace RssLib\Objects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RssLib\Classes\Utilities;
|
||||
use RssLib\Interfaces\SerializableObjectInterface;
|
||||
use RssLib\Objects\RssFeed\Enclosure;
|
||||
use RssLib\Objects\RssFeed\Guid;
|
||||
use RssLib\Objects\RssFeed\Source;
|
||||
|
||||
class RssItem implements SerializableObjectInterface
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $link;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $author;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
private $categories;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $comments;
|
||||
|
||||
/**
|
||||
* @var Enclosure|null
|
||||
*/
|
||||
private $enclosure;
|
||||
|
||||
/**
|
||||
* @var Guid|null
|
||||
*/
|
||||
private $guid;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $publish_date;
|
||||
|
||||
/**
|
||||
* @var Source|null
|
||||
*/
|
||||
private $source;
|
||||
|
||||
/**
|
||||
* RssFeed constructor.
|
||||
*
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
foreach(['title', 'link', 'description'] as $key)
|
||||
{
|
||||
if(!array_key_exists($key, $data))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Missing required key %s for RssFeed', $key));
|
||||
}
|
||||
}
|
||||
|
||||
$this->title = (string)$data['title'];
|
||||
$this->link = (string)$data['link'];
|
||||
$this->description = (string)$data['description'];
|
||||
|
||||
if(array_key_exists('author', $data))
|
||||
{
|
||||
$this->author = (string)$data['author'];
|
||||
}
|
||||
|
||||
if(array_key_exists('categories', $data))
|
||||
{
|
||||
if(is_string($data['categories']))
|
||||
{
|
||||
$this->categories = [$data['categories']];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->categories = (array)$data['categories'];
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists('comments', $data))
|
||||
{
|
||||
$this->comments = (string)$data['comments'];
|
||||
}
|
||||
|
||||
if(array_key_exists('enclosure', $data))
|
||||
{
|
||||
$this->enclosure = new Enclosure($data['enclosure']);
|
||||
}
|
||||
|
||||
if(array_key_exists('guid', $data))
|
||||
{
|
||||
$this->guid = new Guid($data['guid']);
|
||||
}
|
||||
|
||||
if(array_key_exists('pubDate', $data))
|
||||
{
|
||||
$this->publish_date = Utilities::parseTimestamp($data['pubDate']);
|
||||
}
|
||||
|
||||
if(array_key_exists('source', $data))
|
||||
{
|
||||
$this->source = new Source($data['source']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title of the item.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the link of the item.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLink(): ?string
|
||||
{
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the item.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the author of the item.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAuthor(): ?string
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the categories of the item.
|
||||
*
|
||||
* @return string[]|null
|
||||
*/
|
||||
public function getCategories(): array|null
|
||||
{
|
||||
return $this->categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the comments of the item.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getComments(): ?string
|
||||
{
|
||||
return $this->comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the enclosure of the item.
|
||||
*
|
||||
* @return Enclosure|null
|
||||
*/
|
||||
public function getEnclosure(): ?Enclosure
|
||||
{
|
||||
return $this->enclosure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GUID of the item.
|
||||
*
|
||||
* @return Guid|null
|
||||
*/
|
||||
public function getGuid(): ?Guid
|
||||
{
|
||||
return $this->guid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the publication date of the item.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getPublishDate(): ?int
|
||||
{
|
||||
return $this->publish_date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source of the item.
|
||||
*
|
||||
* @return Source|null
|
||||
*/
|
||||
public function getSource(): ?Source
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'link' => $this->link,
|
||||
'description' => $this->description,
|
||||
'author' => $this->author,
|
||||
'categories' => $this->categories,
|
||||
'comments' => $this->comments,
|
||||
'enclosure' => $this->enclosure?->toArray(),
|
||||
'guid' => $this->guid?->toArray(),
|
||||
'pubDate' => $this->publish_date,
|
||||
'source' => $this->source?->toArray(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function fromArray(array $array): SerializableObjectInterface
|
||||
{
|
||||
return new self($array);
|
||||
}
|
||||
}
|
70
src/RssLib/RssLib.php
Normal file
70
src/RssLib/RssLib.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace RssLib;
|
||||
|
||||
use Exception;
|
||||
use RssLib\Classes\Utilities;
|
||||
use RssLib\Exceptions\RssFeedException;
|
||||
use RssLib\Objects\RssChannel;
|
||||
|
||||
class RssLib
|
||||
{
|
||||
/**
|
||||
* @param string $url
|
||||
* @param int $timeout
|
||||
* @return RssChannel
|
||||
* @throws RssFeedException
|
||||
*/
|
||||
public static function getFeed(string $url, int $timeout=120): RssChannel
|
||||
{
|
||||
return self::parseRssContent(self::fetchRssContent($url, $timeout));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the RSS feed from the given URL and returns the content.
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $timeout
|
||||
* @return string
|
||||
* @throws RssFeedException
|
||||
*/
|
||||
public static function fetchRssContent(string $url, int $timeout=120): string
|
||||
{
|
||||
try
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
|
||||
$content = curl_exec($ch);
|
||||
|
||||
if(curl_errno($ch))
|
||||
{
|
||||
throw new RssFeedException(sprintf('Failed to fetch RSS feed from %s: %s', $url, curl_error($ch)));
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new RssFeedException(sprintf('Failed to fetch RSS feed from %s', $url), 0, $e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
curl_close($ch);
|
||||
unset($ch);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @return RssChannel
|
||||
*/
|
||||
public static function parseRssContent(string $content): RssChannel
|
||||
{
|
||||
return new RssChannel(Utilities::xmlToArray(simplexml_load_string($content))['channel']);
|
||||
}
|
||||
}
|
8
tests/parse_test.php
Normal file
8
tests/parse_test.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
require 'ncc';
|
||||
import('net.nosial.rsslib');
|
||||
|
||||
$feed = \RssLib\RssLib::getFeed('https://rss.nytimes.com/services/xml/rss/nyt/World.xml');
|
||||
var_dump($feed);
|
||||
|
Loading…
Add table
Reference in a new issue