Version Description
(2016-02-02) = * Fixed bug: Some exceptions used to cause fatal errors. * Fixed bug: Requests made by image caching used to always have an infinite timeout. * Fixed bug: Licensing algorithm used to use constants of inactive plugins, causing fatal error. * Enhanced: Visual improvements. * Enhanced: Included new Object Oriented code.
Download this release
Release Info
Developer | markzahra |
Plugin | WP RSS Aggregator |
Version | 4.8.1 |
Comparing to | |
See all releases |
Code changes from version 4.8 to 4.8.1
- css/admin-styles.css +6 -6
- includes/Aventura/Wprss/Core/Component/EventManager.php +13 -0
- includes/Aventura/Wprss/Core/Component/Logger.php +126 -0
- includes/Aventura/Wprss/Core/ComponentFactory.php +49 -0
- includes/Aventura/Wprss/Core/DataObject.php +871 -0
- includes/Aventura/Wprss/Core/DataObjectInterface.php +36 -0
- includes/Aventura/Wprss/Core/Exception.php +12 -0
- includes/Aventura/Wprss/Core/Factory.php +23 -0
- includes/Aventura/Wprss/Core/Licensing/Api/Exception.php +14 -0
- includes/Aventura/Wprss/Core/Licensing/Api/RequestException.php +11 -0
- includes/Aventura/Wprss/Core/Licensing/Api/ResponseException.php +12 -0
- includes/Aventura/Wprss/Core/Licensing/Exception.php +14 -0
- includes/Aventura/Wprss/Core/Licensing/Manager.php +44 -21
- includes/Aventura/Wprss/Core/Licensing/Plugin/Exception.php +15 -0
- includes/Aventura/Wprss/Core/Licensing/Plugin/UpdaterException.php +12 -0
- includes/Aventura/Wprss/Core/Model/AssetsAbstract.php +610 -0
- includes/Aventura/Wprss/Core/Model/AssetsInterface.php +39 -0
- includes/Aventura/Wprss/Core/Model/Command.php +15 -0
- includes/Aventura/Wprss/Core/Model/CommandAbstract.php +138 -0
- includes/Aventura/Wprss/Core/Model/CommandException.php +14 -0
- includes/Aventura/Wprss/Core/Model/CommandInterface.php +20 -0
- includes/Aventura/Wprss/Core/Model/Event/Event.php +11 -0
- includes/Aventura/Wprss/Core/Model/Event/EventAbstract.php +83 -0
- includes/Aventura/Wprss/Core/Model/Event/EventInterface.php +33 -0
- includes/Aventura/Wprss/Core/Model/Event/EventManagerAbstract.php +168 -0
- includes/Aventura/Wprss/Core/Model/Event/EventManagerInterface.php +33 -0
- includes/Aventura/Wprss/Core/Model/LoggerAbstract.php +364 -0
- includes/Aventura/Wprss/Core/Model/LoggerInterface.php +118 -0
- includes/Aventura/Wprss/Core/Model/ModelAbstract.php +362 -0
- includes/Aventura/Wprss/Core/Model/ModelInterface.php +72 -0
- includes/Aventura/Wprss/Core/Model/SettingsAbstract.php +862 -0
- includes/Aventura/Wprss/Core/Model/SettingsInterface.php +17 -0
- includes/Aventura/Wprss/Core/Model/SpinnerAbstract.php +24 -0
- includes/Aventura/Wprss/Core/Model/SpinnerApiAbstract.php +86 -0
- includes/Aventura/Wprss/Core/Model/SpinnerApiInterface.php +20 -0
- includes/Aventura/Wprss/Core/Model/SpinnerInterface.php +18 -0
- includes/Aventura/Wprss/Core/Plugin.php +15 -0
- includes/Aventura/Wprss/Core/Plugin/AddonAbstract.php +130 -0
- includes/Aventura/Wprss/Core/Plugin/AddonFactoryAbstract.php +12 -0
- includes/Aventura/Wprss/Core/Plugin/AddonFactoryInterface.php +28 -0
- includes/Aventura/Wprss/Core/Plugin/AddonInterface.php +18 -0
- includes/Aventura/Wprss/Core/Plugin/ComponentAbstract.php +168 -0
- includes/Aventura/Wprss/Core/Plugin/ComponentFactoryAbstract.php +64 -0
- includes/Aventura/Wprss/Core/Plugin/ComponentFactoryInterface.php +17 -0
- includes/Aventura/Wprss/Core/Plugin/ComponentInterface.php +67 -0
- includes/Aventura/Wprss/Core/Plugin/Exception.php +15 -0
- includes/Aventura/Wprss/Core/Plugin/FactoryAbstract.php +50 -0
- includes/Aventura/Wprss/Core/Plugin/FactoryInterface.php +19 -0
- includes/Aventura/Wprss/Core/Plugin/PluginAbstract.php +359 -0
- includes/Aventura/Wprss/Core/Plugin/PluginInterface.php +138 -0
- includes/admin-addons.php +70 -69
- includes/admin-dashboard.php +30 -2
- includes/admin-help.php +28 -12
- includes/functions.php +159 -0
- includes/image-caching.php +1 -1
- includes/system-info.php +4 -1
- readme.txt +69 -772
- wp-rss-aggregator.php +56 -3
css/admin-styles.css
CHANGED
@@ -8,6 +8,10 @@ body.post-type-wprss_feed q:after {
|
|
8 |
content: '"';
|
9 |
}
|
10 |
|
|
|
|
|
|
|
|
|
11 |
.wprss-input {
|
12 |
background: none repeat scroll 0 0 #EAF2FA;
|
13 |
margin-bottom: 20px;
|
@@ -509,17 +513,13 @@ i.wprss-updating-feed-icon.wprss-show {
|
|
509 |
#add-ons .add-on {
|
510 |
float: left;
|
511 |
width: 220px;
|
512 |
-
margin: 10px;
|
513 |
-
|
514 |
border: 1px solid #E5E5E5;
|
515 |
position: relative;
|
516 |
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
|
517 |
}
|
518 |
|
519 |
-
#add-ons .add-on:first-child {
|
520 |
-
margin-left: 0px;
|
521 |
-
}
|
522 |
-
|
523 |
#add-ons .add-on h3 {
|
524 |
margin-top: 0.5em;
|
525 |
}
|
8 |
content: '"';
|
9 |
}
|
10 |
|
11 |
+
span.wp-rss-footer-text {
|
12 |
+
font-style: italic;
|
13 |
+
}
|
14 |
+
|
15 |
.wprss-input {
|
16 |
background: none repeat scroll 0 0 #EAF2FA;
|
17 |
margin-bottom: 20px;
|
513 |
#add-ons .add-on {
|
514 |
float: left;
|
515 |
width: 220px;
|
516 |
+
margin: 10px 20px 10px 0;
|
517 |
+
background: #FFFFFF;
|
518 |
border: 1px solid #E5E5E5;
|
519 |
position: relative;
|
520 |
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
|
521 |
}
|
522 |
|
|
|
|
|
|
|
|
|
523 |
#add-ons .add-on h3 {
|
524 |
margin-top: 0.5em;
|
525 |
}
|
includes/Aventura/Wprss/Core/Component/EventManager.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Component;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
class EventManager extends Core\Model\Event\EventManagerAbstract implements Core\Plugin\ComponentInterface
|
11 |
+
{
|
12 |
+
// All functionality is in most cases reusable from the ancestor
|
13 |
+
}
|
includes/Aventura/Wprss/Core/Component/Logger.php
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Component;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* A WPRSS-specific implementation, ready to use.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
class Logger extends Core\Model\LoggerAbstract
|
13 |
+
{
|
14 |
+
const WPRA_LEVEL_PREFIX = 'WPRSS_LOG_LEVEL_';
|
15 |
+
|
16 |
+
/**
|
17 |
+
* {@inheritdoc}
|
18 |
+
*
|
19 |
+
* Adds an aditional 'SYSTEM' > 'DEBUG' level conversion.
|
20 |
+
*
|
21 |
+
* @since 4.8.1
|
22 |
+
* @param string $level
|
23 |
+
* @return int
|
24 |
+
*/
|
25 |
+
public static function toMonologLevel($level)
|
26 |
+
{
|
27 |
+
// For compatibility with WPRA
|
28 |
+
if (strtoupper($level) === 'SYSTEM') {
|
29 |
+
$level = 'DEBUG';
|
30 |
+
}
|
31 |
+
return parent::toMonologLevel($level);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* {@inheritdoc}
|
36 |
+
*
|
37 |
+
* @since 4.8.1
|
38 |
+
*/
|
39 |
+
public function shouldAddRecord($level, $message, array $context = array())
|
40 |
+
{
|
41 |
+
return $this->shouldLogLevel($level);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* {@inheritdoc}
|
46 |
+
*
|
47 |
+
* @since 4.8.1
|
48 |
+
* @see getLevelThreshold()
|
49 |
+
* @param int|string $level A Monolog level to check.
|
50 |
+
* @return boolean True if the level should be logged; false otherwise.
|
51 |
+
*/
|
52 |
+
public function shouldLogLevel($level)
|
53 |
+
{
|
54 |
+
$level = static::monologToWpraLevel($level);
|
55 |
+
$threshold = $this->getLevelThreshold();
|
56 |
+
if (is_null($threshold)) {
|
57 |
+
return true;
|
58 |
+
}
|
59 |
+
|
60 |
+
$threshold = intval($threshold);
|
61 |
+
if ($threshold === 0) {
|
62 |
+
return false;
|
63 |
+
}
|
64 |
+
|
65 |
+
$thisLevelOnly = $threshold > 0;
|
66 |
+
$threshold = abs($threshold);
|
67 |
+
|
68 |
+
return $thisLevelOnly
|
69 |
+
? $level === $threshold
|
70 |
+
: $level <= $threshold;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Converts a WPRA level to a Monolog one.
|
75 |
+
*
|
76 |
+
* @since 4.8.1
|
77 |
+
* @param int"string $level A numeric or string representation of a WPRA level.
|
78 |
+
* If is WPRA-prefixed, i.e. a full constant name, the prefix will be removed.
|
79 |
+
* @return int The numeric representation of the corresponding Monolog level.
|
80 |
+
* @throws \InvalidArgumentException If no such Monolog level defined.
|
81 |
+
*/
|
82 |
+
public static function wpraToMonologLevel($level)
|
83 |
+
{
|
84 |
+
$wpraPrefix = static::WPRA_LEVEL_PREFIX;
|
85 |
+
if (!is_numeric($level) && stripos($level, $wpraPrefix)) {
|
86 |
+
$level = substr($level, strlen($wpraPrefix));
|
87 |
+
}
|
88 |
+
|
89 |
+
if (is_string($level) || $level > 50) {
|
90 |
+
return static::toMonologLevel($level);
|
91 |
+
}
|
92 |
+
|
93 |
+
$levels = wprss_log_get_levels();
|
94 |
+
if (!isset($levels[$level])) {
|
95 |
+
throw new \InvalidArgumentException(sprintf('Monolog Level "%1$s" is not defined', $level));
|
96 |
+
}
|
97 |
+
|
98 |
+
$level = $levels[$level];
|
99 |
+
return static::toMonologLevel($level);
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Converts a Monolog level to a WPRA one.
|
104 |
+
*
|
105 |
+
* @since 4.8.1
|
106 |
+
* @param string|int $level A Monolog level's string or numeric representation.
|
107 |
+
* @return int The WPRA level's numeric representation that corresponds to the specified Monolog one.
|
108 |
+
* @throws \InvalidArgumentException If no such WPRA level defined.
|
109 |
+
*/
|
110 |
+
public static function monologToWpraLevel($level)
|
111 |
+
{
|
112 |
+
if (is_numeric($level)) {
|
113 |
+
$level = static::getLevelName($level);
|
114 |
+
}
|
115 |
+
if ($level === 'DEBUG') {
|
116 |
+
$level = 'SYSTEM';
|
117 |
+
}
|
118 |
+
|
119 |
+
$constName = static::WPRA_LEVEL_PREFIX . $level;
|
120 |
+
if (!defined($constName)) {
|
121 |
+
throw new \InvalidArgumentException(sprintf('WPRA Level "%1$s" is not defined', $level));
|
122 |
+
}
|
123 |
+
|
124 |
+
return constant($constName);
|
125 |
+
}
|
126 |
+
}
|
includes/Aventura/Wprss/Core/ComponentFactory.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// This whole namespace is a temporary one, until there's a real Core add-on
|
4 |
+
namespace Aventura\Wprss\Core;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* A dummy factory of Core components.
|
8 |
+
*
|
9 |
+
* This is to be used with the Core plugin.
|
10 |
+
*
|
11 |
+
* @todo Create a real Core factory of Core components in the Core plugin.
|
12 |
+
* @since 4.8.1
|
13 |
+
*/
|
14 |
+
class ComponentFactory extends Plugin\ComponentFactoryAbstract
|
15 |
+
{
|
16 |
+
/**
|
17 |
+
* @since 4.8.1
|
18 |
+
*/
|
19 |
+
protected function _construct()
|
20 |
+
{
|
21 |
+
parent::_construct();
|
22 |
+
$this->setBaseNamespace(__NAMESPACE__ . '\\Component');
|
23 |
+
}
|
24 |
+
|
25 |
+
public function createLogger($data = array())
|
26 |
+
{
|
27 |
+
$logger = $this->createComponent('Logger', $this->getPlugin());
|
28 |
+
if (!isset($data['log_file_path'])) {
|
29 |
+
$data['log_file_path'] = WPRSS_LOG_FILE . '-' . get_current_blog_id() . WPRSS_LOG_FILE_EXT;
|
30 |
+
}
|
31 |
+
if (!isset($data['level_threshold'])) {
|
32 |
+
$data['level_threshold'] = wprss_log_get_level();
|
33 |
+
}
|
34 |
+
$logger->addData($data);
|
35 |
+
|
36 |
+
return $logger;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @since 4.8.1
|
41 |
+
* @param array $data
|
42 |
+
* @return Model\Event\EventManagerInterface
|
43 |
+
*/
|
44 |
+
public function createEventManager($data = array())
|
45 |
+
{
|
46 |
+
$events = $this->createComponent('EventManager', $this->getPlugin(), $data);
|
47 |
+
return $events;
|
48 |
+
}
|
49 |
+
}
|
includes/Aventura/Wprss/Core/DataObject.php
ADDED
@@ -0,0 +1,871 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* An object with dynamic getter and setter functionality, as well as array access.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
class DataObject implements \ArrayAccess, DataObjectInterface {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Object attributes
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
protected $_data = array();
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Data changes flag (true after setData|unsetData call)
|
22 |
+
* @since 4.8.1
|
23 |
+
* @var $_hasDataChange bool
|
24 |
+
*/
|
25 |
+
protected $_hasDataChanges = false;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Original data that was loaded
|
29 |
+
*
|
30 |
+
* @since 4.8.1
|
31 |
+
* @var array
|
32 |
+
*/
|
33 |
+
protected $_origData;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Name of object id field
|
37 |
+
*
|
38 |
+
* @since 4.8.1
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
protected $_idFieldName = null;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Setter/Getter underscore transformation cache
|
45 |
+
*
|
46 |
+
* @since 4.8.1
|
47 |
+
* @var array
|
48 |
+
*/
|
49 |
+
protected static $_underscoreCache = array();
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Object delete flag
|
53 |
+
*
|
54 |
+
* @since 4.8.1
|
55 |
+
* @var boolean
|
56 |
+
*/
|
57 |
+
protected $_isDeleted = false;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Constructor
|
61 |
+
*
|
62 |
+
* By default is looking for first argument as array and assignes it as object attributes
|
63 |
+
* This behaviour may change in child classes
|
64 |
+
*
|
65 |
+
* @since 4.8.1
|
66 |
+
*/
|
67 |
+
public function __construct() {
|
68 |
+
$args = func_get_args();
|
69 |
+
if (empty($args[0])) {
|
70 |
+
$args[0] = array();
|
71 |
+
}
|
72 |
+
$this->_data = $args[0];
|
73 |
+
|
74 |
+
$this->_construct();
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Internal constructor not depended on params. Can be used for object initialization.
|
79 |
+
*
|
80 |
+
* If you want to add some procedures that happen on instantiation,
|
81 |
+
* you probably want to override this.
|
82 |
+
*
|
83 |
+
* @since 4.8.1
|
84 |
+
*/
|
85 |
+
protected function _construct() {}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Set _isDeleted flag value (if $isDeleted param is defined) and return current flag value
|
89 |
+
*
|
90 |
+
* @since 4.8.1
|
91 |
+
* @param boolean $isDeleted
|
92 |
+
* @return boolean
|
93 |
+
*/
|
94 |
+
public function isDeleted($isDeleted=null)
|
95 |
+
{
|
96 |
+
$result = $this->_isDeleted;
|
97 |
+
if (!is_null($isDeleted)) {
|
98 |
+
$this->_isDeleted = $isDeleted;
|
99 |
+
}
|
100 |
+
return $result;
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Get data change status
|
105 |
+
*
|
106 |
+
* @since 4.8.1
|
107 |
+
* @return bool
|
108 |
+
*/
|
109 |
+
public function hasDataChanges()
|
110 |
+
{
|
111 |
+
return $this->_hasDataChanges;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* set name of object id field
|
116 |
+
*
|
117 |
+
* @since 4.8.1
|
118 |
+
* @param string $name
|
119 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
120 |
+
*/
|
121 |
+
public function setIdFieldName($name)
|
122 |
+
{
|
123 |
+
$this->_idFieldName = $name;
|
124 |
+
return $this;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Retrieve name of object id field
|
129 |
+
*
|
130 |
+
* @since 4.8.1
|
131 |
+
* @param string $name
|
132 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
133 |
+
*/
|
134 |
+
public function getIdFieldName()
|
135 |
+
{
|
136 |
+
return $this->_idFieldName;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Retrieve object id
|
141 |
+
*
|
142 |
+
* @since 4.8.1
|
143 |
+
* @return mixed
|
144 |
+
*/
|
145 |
+
public function getId()
|
146 |
+
{
|
147 |
+
if ($this->getIdFieldName()) {
|
148 |
+
return $this->_getData($this->getIdFieldName());
|
149 |
+
}
|
150 |
+
return $this->_getData('id');
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Set object id field value
|
155 |
+
*
|
156 |
+
* @since 4.8.1
|
157 |
+
* @param mixed $value
|
158 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
159 |
+
*/
|
160 |
+
public function setId($value)
|
161 |
+
{
|
162 |
+
if ($this->getIdFieldName()) {
|
163 |
+
$this->setData($this->getIdFieldName(), $value);
|
164 |
+
} else {
|
165 |
+
$this->setData('id', $value);
|
166 |
+
}
|
167 |
+
return $this;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Add data to the object.
|
172 |
+
*
|
173 |
+
* Retains previous data in the object.
|
174 |
+
*
|
175 |
+
* @since 4.8.1
|
176 |
+
* @param array $arr
|
177 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
178 |
+
*/
|
179 |
+
public function addData(array $arr)
|
180 |
+
{
|
181 |
+
foreach($arr as $index=>$value) {
|
182 |
+
$this->setData($index, $value);
|
183 |
+
}
|
184 |
+
return $this;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Overwrite data in the object.
|
189 |
+
*
|
190 |
+
* $key can be string or array.
|
191 |
+
* If $key is string, the attribute value will be overwritten by $value
|
192 |
+
*
|
193 |
+
* If $key is an array, it will overwrite all the data in the object.
|
194 |
+
*
|
195 |
+
* @since 4.8.1
|
196 |
+
* @param string|array $key
|
197 |
+
* @param mixed $value
|
198 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
199 |
+
*/
|
200 |
+
public function setData($key, $value=null)
|
201 |
+
{
|
202 |
+
$this->_hasDataChanges = true;
|
203 |
+
// http://www.php.net/manual/en/function.is-array.php#48083
|
204 |
+
if(is_array($key)) {
|
205 |
+
$this->_data = $key;
|
206 |
+
} else {
|
207 |
+
$this->_data[$key] = $value;
|
208 |
+
}
|
209 |
+
return $this;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Unset data from the object.
|
214 |
+
*
|
215 |
+
* $key can be a string only. Array will be ignored.
|
216 |
+
*
|
217 |
+
* @since 4.8.1
|
218 |
+
* @param string $key
|
219 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
220 |
+
*/
|
221 |
+
public function unsetData($key=null)
|
222 |
+
{
|
223 |
+
$this->_hasDataChanges = true;
|
224 |
+
if (is_null($key)) {
|
225 |
+
$this->_data = array();
|
226 |
+
} else {
|
227 |
+
unset($this->_data[$key]);
|
228 |
+
}
|
229 |
+
return $this;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Retrieves data from the object
|
234 |
+
*
|
235 |
+
* If $key is empty will return all the data as an array
|
236 |
+
* Otherwise it will return value of the attribute specified by $key
|
237 |
+
*
|
238 |
+
* If $index is specified it will assume that attribute data is an array
|
239 |
+
* and retrieve corresponding member.
|
240 |
+
*
|
241 |
+
* @since 4.8.1
|
242 |
+
* @param string $key
|
243 |
+
* @param string|int $index
|
244 |
+
* @return mixed
|
245 |
+
*/
|
246 |
+
public function getData($key='', $index=null)
|
247 |
+
{
|
248 |
+
if (''===$key) {
|
249 |
+
return $this->_data;
|
250 |
+
}
|
251 |
+
|
252 |
+
if (is_array($key)) {
|
253 |
+
return array_pick($this->_data, $key);
|
254 |
+
}
|
255 |
+
|
256 |
+
$default = null;
|
257 |
+
|
258 |
+
// accept a/b/c as ['a']['b']['c']
|
259 |
+
if (strpos($key,'/')) {
|
260 |
+
$keyArr = explode('/', $key);
|
261 |
+
$data = $this->_data;
|
262 |
+
foreach ($keyArr as $i=>$k) {
|
263 |
+
if ($k==='') {
|
264 |
+
return $default;
|
265 |
+
}
|
266 |
+
if (is_array($data)) {
|
267 |
+
if (!isset($data[$k])) {
|
268 |
+
return $default;
|
269 |
+
}
|
270 |
+
$data = $data[$k];
|
271 |
+
} elseif ($data instanceof Wp_Rss_SpinnerChief_Data_Object) {
|
272 |
+
$data = $data->getData($k);
|
273 |
+
} else {
|
274 |
+
return $default;
|
275 |
+
}
|
276 |
+
}
|
277 |
+
return $data;
|
278 |
+
}
|
279 |
+
|
280 |
+
// legacy functionality for $index
|
281 |
+
if (isset($this->_data[$key])) {
|
282 |
+
if (is_null($index)) {
|
283 |
+
return $this->_data[$key];
|
284 |
+
}
|
285 |
+
|
286 |
+
$value = $this->_data[$key];
|
287 |
+
if (is_array($value)) {
|
288 |
+
//if (isset($value[$index]) && (!empty($value[$index]) || strlen($value[$index]) > 0)) {
|
289 |
+
/**
|
290 |
+
* If we have any data, even if it empty - we should use it, anyway
|
291 |
+
*/
|
292 |
+
if (isset($value[$index])) {
|
293 |
+
return $value[$index];
|
294 |
+
}
|
295 |
+
return null;
|
296 |
+
} elseif (is_string($value)) {
|
297 |
+
$arr = explode("\n", $value);
|
298 |
+
return (isset($arr[$index]) && (!empty($arr[$index]) || strlen($arr[$index]) > 0)) ? $arr[$index] : null;
|
299 |
+
} elseif ($value instanceof Wp_Rss_SpinnerChief_Data_Object) {
|
300 |
+
return $value->getData($index);
|
301 |
+
}
|
302 |
+
return $default;
|
303 |
+
}
|
304 |
+
return $default;
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Get value from _data array without parse key
|
309 |
+
*
|
310 |
+
* @since 4.8.1
|
311 |
+
* @param string $key
|
312 |
+
* @return mixed
|
313 |
+
*/
|
314 |
+
protected function _getData($key)
|
315 |
+
{
|
316 |
+
return isset($this->_data[$key]) ? $this->_data[$key] : null;
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Set object data with calling setter method
|
321 |
+
*
|
322 |
+
* @since 4.8.1
|
323 |
+
* @param string $key
|
324 |
+
* @param mixed $args
|
325 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
326 |
+
*/
|
327 |
+
public function setDataUsingMethod($key, $args=array())
|
328 |
+
{
|
329 |
+
$method = 'set'.$this->_camelize($key);
|
330 |
+
$this->$method($args);
|
331 |
+
return $this;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Get object data by key with calling getter method
|
336 |
+
*
|
337 |
+
* @since 4.8.1
|
338 |
+
* @param string $key
|
339 |
+
* @param mixed $args
|
340 |
+
* @return mixed
|
341 |
+
*/
|
342 |
+
public function getDataUsingMethod($key, $args=null)
|
343 |
+
{
|
344 |
+
$method = 'get'.$this->_camelize($key);
|
345 |
+
return $this->$method($args);
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Fast get data or set default if value is not available
|
350 |
+
*
|
351 |
+
* @since 4.8.1
|
352 |
+
* @param string $key
|
353 |
+
* @param mixed $default
|
354 |
+
* @return mixed
|
355 |
+
*/
|
356 |
+
public function getDataSetDefault($key, $default)
|
357 |
+
{
|
358 |
+
if (!isset($this->_data[$key])) {
|
359 |
+
$this->_data[$key] = $default;
|
360 |
+
}
|
361 |
+
return $this->_data[$key];
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* If $key is empty, checks whether there's any data in the object
|
366 |
+
* Otherwise checks if the specified attribute is set.
|
367 |
+
*
|
368 |
+
* @since 4.8.1
|
369 |
+
* @param string $key
|
370 |
+
* @return boolean
|
371 |
+
*/
|
372 |
+
public function hasData($key='')
|
373 |
+
{
|
374 |
+
if (empty($key) || !is_string($key)) {
|
375 |
+
return !empty($this->_data);
|
376 |
+
}
|
377 |
+
return array_key_exists($key, $this->_data);
|
378 |
+
}
|
379 |
+
|
380 |
+
/**
|
381 |
+
* Convert object attributes to array
|
382 |
+
*
|
383 |
+
* @since 4.8.1
|
384 |
+
* @param array $arrAttributes array of required attributes
|
385 |
+
* @return array
|
386 |
+
*/
|
387 |
+
public function __toArray(array $arrAttributes = array())
|
388 |
+
{
|
389 |
+
if (empty($arrAttributes)) {
|
390 |
+
return $this->_data;
|
391 |
+
}
|
392 |
+
|
393 |
+
$arrRes = array();
|
394 |
+
foreach ($arrAttributes as $attribute) {
|
395 |
+
if (isset($this->_data[$attribute])) {
|
396 |
+
$arrRes[$attribute] = $this->_data[$attribute];
|
397 |
+
}
|
398 |
+
else {
|
399 |
+
$arrRes[$attribute] = null;
|
400 |
+
}
|
401 |
+
}
|
402 |
+
return $arrRes;
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Public wrapper for __toArray
|
407 |
+
*
|
408 |
+
* @since 4.8.1
|
409 |
+
* @param array $arrAttributes
|
410 |
+
* @return array
|
411 |
+
*/
|
412 |
+
public function toArray(array $arrAttributes = array())
|
413 |
+
{
|
414 |
+
return $this->__toArray($arrAttributes);
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Set required array elements
|
419 |
+
*
|
420 |
+
* @since 4.8.1
|
421 |
+
* @param array $arr
|
422 |
+
* @param array $elements
|
423 |
+
* @return array
|
424 |
+
*/
|
425 |
+
protected function _prepareArray(&$arr, array $elements=array())
|
426 |
+
{
|
427 |
+
foreach ($elements as $element) {
|
428 |
+
if (!isset($arr[$element])) {
|
429 |
+
$arr[$element] = null;
|
430 |
+
}
|
431 |
+
}
|
432 |
+
return $arr;
|
433 |
+
}
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Convert object attributes to XML
|
437 |
+
*
|
438 |
+
* @since 4.8.1
|
439 |
+
* @param array $arrAttributes array of required attributes
|
440 |
+
* @param string $rootName name of the root element
|
441 |
+
* @return string
|
442 |
+
*/
|
443 |
+
protected function __toXml(array $arrAttributes = array(), $rootName = 'item', $addOpenTag=false, $addCdata=true)
|
444 |
+
{
|
445 |
+
$xml = '';
|
446 |
+
if ($addOpenTag) {
|
447 |
+
$xml.= '<?xml version="1.0" encoding="UTF-8"?>'."\n";
|
448 |
+
}
|
449 |
+
if (!empty($rootName)) {
|
450 |
+
$xml.= '<'.$rootName.'>'."\n";
|
451 |
+
}
|
452 |
+
$xmlModel = new Varien_Simplexml_Element('<node></node>');
|
453 |
+
$arrData = $this->toArray($arrAttributes);
|
454 |
+
foreach ($arrData as $fieldName => $fieldValue) {
|
455 |
+
if ($addCdata === true) {
|
456 |
+
$fieldValue = "<![CDATA[$fieldValue]]>";
|
457 |
+
} else {
|
458 |
+
$fieldValue = $xmlModel->xmlentities($fieldValue);
|
459 |
+
}
|
460 |
+
$xml.= "<$fieldName>$fieldValue</$fieldName>"."\n";
|
461 |
+
}
|
462 |
+
if (!empty($rootName)) {
|
463 |
+
$xml.= '</'.$rootName.'>'."\n";
|
464 |
+
}
|
465 |
+
return $xml;
|
466 |
+
}
|
467 |
+
|
468 |
+
/**
|
469 |
+
* Public wrapper for __toXml
|
470 |
+
*
|
471 |
+
* @since 4.8.1
|
472 |
+
* @param array $arrAttributes
|
473 |
+
* @param string $rootName
|
474 |
+
* @return string
|
475 |
+
*/
|
476 |
+
public function toXml(array $arrAttributes = array(), $rootName = 'item', $addOpenTag=false, $addCdata=true)
|
477 |
+
{
|
478 |
+
return $this->__toXml($arrAttributes, $rootName, $addOpenTag, $addCdata);
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Convert object attributes to JSON
|
483 |
+
*
|
484 |
+
* @since 4.8.1
|
485 |
+
* @param array $arrAttributes array of required attributes
|
486 |
+
* @return string
|
487 |
+
*/
|
488 |
+
protected function __toJson(array $arrAttributes = array())
|
489 |
+
{
|
490 |
+
$arrData = $this->toArray($arrAttributes);
|
491 |
+
$json = Zend_Json::encode($arrData);
|
492 |
+
return $json;
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Public wrapper for __toJson
|
497 |
+
*
|
498 |
+
* @since 4.8.1
|
499 |
+
* @param array $arrAttributes
|
500 |
+
* @return string
|
501 |
+
*/
|
502 |
+
public function toJson(array $arrAttributes = array())
|
503 |
+
{
|
504 |
+
return $this->__toJson($arrAttributes);
|
505 |
+
}
|
506 |
+
|
507 |
+
/**
|
508 |
+
* Convert object attributes to string
|
509 |
+
*
|
510 |
+
* @since 4.8.1
|
511 |
+
* @param array $arrAttributes array of required attributes
|
512 |
+
* @param string $valueSeparator
|
513 |
+
* @return string
|
514 |
+
*/
|
515 |
+
// public function __toString(array $arrAttributes = array(), $valueSeparator=',')
|
516 |
+
// {
|
517 |
+
// $arrData = $this->toArray($arrAttributes);
|
518 |
+
// return implode($valueSeparator, $arrData);
|
519 |
+
// }
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Public wrapper for __toString
|
523 |
+
*
|
524 |
+
* Will use $format as an template and substitute {{key}} for attributes
|
525 |
+
*
|
526 |
+
* @since 4.8.1
|
527 |
+
* @param string $format
|
528 |
+
* @return string
|
529 |
+
*/
|
530 |
+
public function toString($format='')
|
531 |
+
{
|
532 |
+
if (empty($format)) {
|
533 |
+
$str = implode(', ', $this->getData());
|
534 |
+
} else {
|
535 |
+
preg_match_all('/\{\{([a-z0-9_]+)\}\}/is', $format, $matches);
|
536 |
+
foreach ($matches[1] as $var) {
|
537 |
+
$format = str_replace('{{'.$var.'}}', $this->getData($var), $format);
|
538 |
+
}
|
539 |
+
$str = $format;
|
540 |
+
}
|
541 |
+
return $str;
|
542 |
+
}
|
543 |
+
|
544 |
+
/**
|
545 |
+
* Set/Get attribute wrapper
|
546 |
+
*
|
547 |
+
* @since 4.8.1
|
548 |
+
* @param string $method
|
549 |
+
* @param array $args
|
550 |
+
* @return mixed
|
551 |
+
*/
|
552 |
+
public function __call( $method, $args ) {
|
553 |
+
switch (substr($method, 0, 3)) {
|
554 |
+
case 'get' :
|
555 |
+
$key = $this->_underscore(substr($method,3));
|
556 |
+
$data = $this->getData($key, isset($args[0]) ? $args[0] : null);
|
557 |
+
return $data;
|
558 |
+
|
559 |
+
case 'set' :
|
560 |
+
$key = $this->_underscore(substr($method,3));
|
561 |
+
$result = $this->setData($key, isset($args[0]) ? $args[0] : null);
|
562 |
+
return $result;
|
563 |
+
|
564 |
+
case 'uns' :
|
565 |
+
$key = $this->_underscore(substr($method,3));
|
566 |
+
$result = $this->unsetData($key);
|
567 |
+
return $result;
|
568 |
+
|
569 |
+
case 'has' :
|
570 |
+
$key = $this->_underscore(substr($method,3));
|
571 |
+
return isset($this->_data[$key]);
|
572 |
+
}
|
573 |
+
throw new Exception("Invalid method ".get_class($this)."::".$method."(".print_r($args,1).")");
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* Attribute getter (deprecated)
|
578 |
+
*
|
579 |
+
* @since 4.8.1
|
580 |
+
* @param string $var
|
581 |
+
* @return mixed
|
582 |
+
*/
|
583 |
+
|
584 |
+
public function __get($var)
|
585 |
+
{
|
586 |
+
$var = $this->_underscore($var);
|
587 |
+
return $this->getData($var);
|
588 |
+
}
|
589 |
+
|
590 |
+
/**
|
591 |
+
* Attribute setter (deprecated)
|
592 |
+
*
|
593 |
+
* @since 4.8.1
|
594 |
+
* @param string $var
|
595 |
+
* @param mixed $value
|
596 |
+
*/
|
597 |
+
public function __set($var, $value)
|
598 |
+
{
|
599 |
+
$var = $this->_underscore($var);
|
600 |
+
$this->setData($var, $value);
|
601 |
+
}
|
602 |
+
|
603 |
+
/**
|
604 |
+
* checks whether the object is empty
|
605 |
+
*
|
606 |
+
* @since 4.8.1
|
607 |
+
* @return boolean
|
608 |
+
*/
|
609 |
+
public function isEmpty()
|
610 |
+
{
|
611 |
+
if (empty($this->_data)) {
|
612 |
+
return true;
|
613 |
+
}
|
614 |
+
return false;
|
615 |
+
}
|
616 |
+
|
617 |
+
/**
|
618 |
+
* Converts field names for setters and geters
|
619 |
+
*
|
620 |
+
* $this->setMyField($value) === $this->setData('my_field', $value)
|
621 |
+
* Uses cache to eliminate unneccessary preg_replace
|
622 |
+
*
|
623 |
+
* @since 4.8.1
|
624 |
+
* @param string $name
|
625 |
+
* @return string
|
626 |
+
*/
|
627 |
+
protected function _underscore($name)
|
628 |
+
{
|
629 |
+
if (isset(self::$_underscoreCache[$name])) {
|
630 |
+
return self::$_underscoreCache[$name];
|
631 |
+
}
|
632 |
+
#Varien_Profiler::start('underscore');
|
633 |
+
$result = strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $name));
|
634 |
+
#Varien_Profiler::stop('underscore');
|
635 |
+
self::$_underscoreCache[$name] = $result;
|
636 |
+
return $result;
|
637 |
+
}
|
638 |
+
|
639 |
+
protected function _camelize($name)
|
640 |
+
{
|
641 |
+
return uc_words($name, '');
|
642 |
+
}
|
643 |
+
|
644 |
+
/**
|
645 |
+
* serialize object attributes
|
646 |
+
*
|
647 |
+
* @since 4.8.1
|
648 |
+
* @param array $attributes
|
649 |
+
* @param string $valueSeparator
|
650 |
+
* @param string $fieldSeparator
|
651 |
+
* @param string $quote
|
652 |
+
* @return string
|
653 |
+
*/
|
654 |
+
public function serialize($attributes = array(), $valueSeparator='=', $fieldSeparator=' ', $quote='"')
|
655 |
+
{
|
656 |
+
$res = '';
|
657 |
+
$data = array();
|
658 |
+
if (empty($attributes)) {
|
659 |
+
$attributes = array_keys($this->_data);
|
660 |
+
}
|
661 |
+
|
662 |
+
foreach ($this->_data as $key => $value) {
|
663 |
+
if (in_array($key, $attributes)) {
|
664 |
+
$data[] = $key . $valueSeparator . $quote . $value . $quote;
|
665 |
+
}
|
666 |
+
}
|
667 |
+
$res = implode($fieldSeparator, $data);
|
668 |
+
return $res;
|
669 |
+
}
|
670 |
+
|
671 |
+
/**
|
672 |
+
* Get object loaded data (original data)
|
673 |
+
*
|
674 |
+
* @since 4.8.1
|
675 |
+
* @param string $key
|
676 |
+
* @return mixed
|
677 |
+
*/
|
678 |
+
public function getOrigData($key=null)
|
679 |
+
{
|
680 |
+
if (is_null($key)) {
|
681 |
+
return $this->_origData;
|
682 |
+
}
|
683 |
+
return isset($this->_origData[$key]) ? $this->_origData[$key] : null;
|
684 |
+
}
|
685 |
+
|
686 |
+
/**
|
687 |
+
* Initialize object original data
|
688 |
+
*
|
689 |
+
* @since 4.8.1
|
690 |
+
* @param string $key
|
691 |
+
* @param mixed $data
|
692 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
693 |
+
*/
|
694 |
+
public function setOrigData($key=null, $data=null)
|
695 |
+
{
|
696 |
+
if (is_null($key)) {
|
697 |
+
$this->_origData = $this->_data;
|
698 |
+
} else {
|
699 |
+
$this->_origData[$key] = $data;
|
700 |
+
}
|
701 |
+
return $this;
|
702 |
+
}
|
703 |
+
|
704 |
+
/**
|
705 |
+
* Compare object data with original data
|
706 |
+
*
|
707 |
+
* @since 4.8.1
|
708 |
+
* @param string $field
|
709 |
+
* @return boolean
|
710 |
+
*/
|
711 |
+
public function dataHasChangedFor($field)
|
712 |
+
{
|
713 |
+
$newData = $this->getData($field);
|
714 |
+
$origData = $this->getOrigData($field);
|
715 |
+
return $newData!=$origData;
|
716 |
+
}
|
717 |
+
|
718 |
+
/**
|
719 |
+
* Clears data changes status
|
720 |
+
*
|
721 |
+
* @since 4.8.1
|
722 |
+
* @param boolean $value
|
723 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
724 |
+
*/
|
725 |
+
public function setDataChanges($value)
|
726 |
+
{
|
727 |
+
$this->_hasDataChanges = (bool)$value;
|
728 |
+
return $this;
|
729 |
+
}
|
730 |
+
|
731 |
+
/**
|
732 |
+
* Present object data as string in debug mode
|
733 |
+
*
|
734 |
+
* @since 4.8.1
|
735 |
+
* @param mixed $data
|
736 |
+
* @param array $objects
|
737 |
+
* @return string
|
738 |
+
*/
|
739 |
+
public function debugSelf($data=null, &$objects=array())
|
740 |
+
{
|
741 |
+
if (is_null($data)) {
|
742 |
+
$hash = spl_object_hash($this);
|
743 |
+
if (!empty($objects[$hash])) {
|
744 |
+
return '*** RECURSION ***';
|
745 |
+
}
|
746 |
+
$objects[$hash] = true;
|
747 |
+
$data = $this->getData();
|
748 |
+
}
|
749 |
+
$debug = array();
|
750 |
+
foreach ($data as $key=>$value) {
|
751 |
+
if (is_scalar($value)) {
|
752 |
+
$debug[$key] = $value;
|
753 |
+
} elseif (is_array($value)) {
|
754 |
+
$debug[$key] = $this->debug($value, $objects);
|
755 |
+
} elseif ($value instanceof Wp_Rss_SpinnerChief_Data_Object) {
|
756 |
+
$debug[$key.' ('.get_class($value).')'] = $value->debug(null, $objects);
|
757 |
+
}
|
758 |
+
}
|
759 |
+
return $debug;
|
760 |
+
}
|
761 |
+
|
762 |
+
/**
|
763 |
+
* Implementation of ArrayAccess::offsetSet()
|
764 |
+
*
|
765 |
+
* @since 4.8.1
|
766 |
+
* @link http://www.php.net/manual/en/arrayaccess.offsetset.php
|
767 |
+
* @param string $offset
|
768 |
+
* @param mixed $value
|
769 |
+
*/
|
770 |
+
public function offsetSet($offset, $value)
|
771 |
+
{
|
772 |
+
$this->_data[$offset] = $value;
|
773 |
+
}
|
774 |
+
|
775 |
+
/**
|
776 |
+
* Implementation of ArrayAccess::offsetExists()
|
777 |
+
*
|
778 |
+
* @since 4.8.1
|
779 |
+
* @link http://www.php.net/manual/en/arrayaccess.offsetexists.php
|
780 |
+
* @param string $offset
|
781 |
+
* @return boolean
|
782 |
+
*/
|
783 |
+
public function offsetExists($offset)
|
784 |
+
{
|
785 |
+
return isset($this->_data[$offset]);
|
786 |
+
}
|
787 |
+
|
788 |
+
/**
|
789 |
+
* Implementation of ArrayAccess::offsetUnset()
|
790 |
+
*
|
791 |
+
* @since 4.8.1
|
792 |
+
* @link http://www.php.net/manual/en/arrayaccess.offsetunset.php
|
793 |
+
* @param string $offset
|
794 |
+
*/
|
795 |
+
public function offsetUnset($offset)
|
796 |
+
{
|
797 |
+
unset($this->_data[$offset]);
|
798 |
+
}
|
799 |
+
|
800 |
+
/**
|
801 |
+
* Implementation of ArrayAccess::offsetGet()
|
802 |
+
*
|
803 |
+
* @since 4.8.1
|
804 |
+
* @link http://www.php.net/manual/en/arrayaccess.offsetget.php
|
805 |
+
* @param string $offset
|
806 |
+
* @return mixed
|
807 |
+
*/
|
808 |
+
public function offsetGet($offset)
|
809 |
+
{
|
810 |
+
return isset($this->_data[$offset]) ? $this->_data[$offset] : null;
|
811 |
+
}
|
812 |
+
|
813 |
+
|
814 |
+
/**
|
815 |
+
* Enter description here...
|
816 |
+
*
|
817 |
+
* @since 4.8.1
|
818 |
+
* @param string $field
|
819 |
+
* @return boolean
|
820 |
+
*/
|
821 |
+
public function isDirty($field=null)
|
822 |
+
{
|
823 |
+
if (empty($this->_dirty)) {
|
824 |
+
return false;
|
825 |
+
}
|
826 |
+
if (is_null($field)) {
|
827 |
+
return true;
|
828 |
+
}
|
829 |
+
return isset($this->_dirty[$field]);
|
830 |
+
}
|
831 |
+
|
832 |
+
/**
|
833 |
+
* Enter description here...
|
834 |
+
*
|
835 |
+
* @since 4.8.1
|
836 |
+
* @param string $field
|
837 |
+
* @param boolean $flag
|
838 |
+
* @return Wp_Rss_SpinnerChief_Data_Object
|
839 |
+
*/
|
840 |
+
public function flagDirty($field, $flag=true)
|
841 |
+
{
|
842 |
+
if (is_null($field)) {
|
843 |
+
foreach ($this->getData() as $field=>$value) {
|
844 |
+
$this->flagDirty($field, $flag);
|
845 |
+
}
|
846 |
+
} else {
|
847 |
+
if ($flag) {
|
848 |
+
$this->_dirty[$field] = true;
|
849 |
+
} else {
|
850 |
+
unset($this->_dirty[$field]);
|
851 |
+
}
|
852 |
+
}
|
853 |
+
return $this;
|
854 |
+
}
|
855 |
+
}
|
856 |
+
|
857 |
+
|
858 |
+
/**
|
859 |
+
* Tiny function to enhance functionality of ucwords
|
860 |
+
*
|
861 |
+
* Will capitalize first letters and convert separators if needed
|
862 |
+
*
|
863 |
+
* @since 4.8.1
|
864 |
+
* @param string $str
|
865 |
+
* @param string $destSep
|
866 |
+
* @param string $srcSep
|
867 |
+
* @return string
|
868 |
+
*/
|
869 |
+
function uc_words($str, $destSep='_', $srcSep='_') {
|
870 |
+
return str_replace(' ', $destSep, ucwords(str_replace($srcSep, ' ', $str)));
|
871 |
+
}
|
includes/Aventura/Wprss/Core/DataObjectInterface.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* An interface for something that can hold and manipulate arbitrary internal data.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface DataObjectInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* @since 4.8.1
|
14 |
+
*/
|
15 |
+
public function getData($key = null);
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @since 4.8.1
|
19 |
+
*/
|
20 |
+
public function hasData($key = null);
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @since 4.8.1
|
24 |
+
*/
|
25 |
+
public function unsetData($key = null);
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @since 4.8.1
|
29 |
+
*/
|
30 |
+
public function setData($key, $value = null);
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @since 4.8.1
|
34 |
+
*/
|
35 |
+
public function setDataUsingMethod($key);
|
36 |
+
}
|
includes/Aventura/Wprss/Core/Exception.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Base class for all WPRA exceptions.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
class Exception extends \Exception
|
11 |
+
{
|
12 |
+
}
|
includes/Aventura/Wprss/Core/Factory.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @since 4.8.1
|
7 |
+
*/
|
8 |
+
class Factory extends Plugin\FactoryAbstract
|
9 |
+
{
|
10 |
+
public function _create($data = array())
|
11 |
+
{
|
12 |
+
$plugin = new Plugin($data);
|
13 |
+
$factory = new ComponentFactory($plugin);
|
14 |
+
$plugin->setFactory($factory);
|
15 |
+
|
16 |
+
$plugin->setLogger($factory->createLogger());
|
17 |
+
$plugin->setEventManager($factory->createEventManager());
|
18 |
+
|
19 |
+
$plugin->hook();
|
20 |
+
|
21 |
+
return $plugin;
|
22 |
+
}
|
23 |
+
}
|
includes/Aventura/Wprss/Core/Licensing/Api/Exception.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Licensing\Api;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core\Licensing;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* When something goes wrong in the WPRSS Licensing API.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
class Exception extends Licensing\Exception
|
13 |
+
{
|
14 |
+
}
|
includes/Aventura/Wprss/Core/Licensing/Api/RequestException.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Licensing\Api;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Thrown when the Licensing API encounters an error related to the HTTP request.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
class RequestException extends Exception {
|
11 |
+
}
|
includes/Aventura/Wprss/Core/Licensing/Api/ResponseException.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Licensing\Api;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Exception class, thrown when the Licensing API responds with an invalid response.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
class ResponseException extends Exception
|
11 |
+
{
|
12 |
+
}
|
includes/Aventura/Wprss/Core/Licensing/Exception.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Licensing;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* When something goes wrong with WPRA licensing.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
class Exception extends Core\Exception
|
13 |
+
{
|
14 |
+
}
|
includes/Aventura/Wprss/Core/Licensing/Manager.php
CHANGED
@@ -1,7 +1,11 @@
|
|
1 |
<?php
|
2 |
|
3 |
namespace Aventura\Wprss\Core\Licensing;
|
|
|
4 |
use \Aventura\Wprss\Core\Licensing\License\Status;
|
|
|
|
|
|
|
5 |
|
6 |
/**
|
7 |
* Manager class for license handling.
|
@@ -430,9 +434,16 @@ class Manager {
|
|
430 |
|
431 |
// Addon Uppercase ID
|
432 |
$addonUid = strtoupper( $addonId );
|
433 |
-
// Prepare constants
|
434 |
-
$
|
435 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
436 |
|
437 |
try {
|
438 |
$licenseData = $this->api($storeUrl, array(
|
@@ -440,10 +451,15 @@ class Manager {
|
|
440 |
'license' => $license,
|
441 |
'item_name' => $itemName,
|
442 |
));
|
443 |
-
}
|
|
|
444 |
wprss_log( sprintf( 'Could not retrieve licensing data from "%1$s": %2$s', $storeUrl, $e->getMessage() ), __FUNCTION__, WPRSS_LOG_LEVEL_WARNING );
|
445 |
return $license->getStatus();
|
446 |
}
|
|
|
|
|
|
|
|
|
447 |
|
448 |
// Update the DB option
|
449 |
$license->setStatus( $licenseData->license );
|
@@ -469,7 +485,8 @@ class Manager {
|
|
469 |
* 'item_name' are required for a successful call. 'license' can also be
|
470 |
* an instance of {@link Aventura\Wprss\Core\Licensing\License}.
|
471 |
* @return object License data as properties of an stdClass instance.
|
472 |
-
* @throws
|
|
|
473 |
*/
|
474 |
public function api($storeUrl, $params) {
|
475 |
$defaultParams = array(
|
@@ -493,16 +510,16 @@ class Manager {
|
|
493 |
|
494 |
// Request failed
|
495 |
if ( is_wp_error( $response ) ) {
|
496 |
-
throw new
|
497 |
}
|
498 |
|
499 |
$body = wp_remote_retrieve_body( $response );
|
500 |
if ( empty( $body ) ) {
|
501 |
-
throw new
|
502 |
}
|
503 |
|
504 |
if ( ($licenseData = json_decode( $body )) === null ) {
|
505 |
-
throw new
|
506 |
}
|
507 |
|
508 |
return $licenseData;
|
@@ -540,18 +557,23 @@ class Manager {
|
|
540 |
return false;
|
541 |
}
|
542 |
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
|
|
|
|
|
|
|
|
|
|
555 |
}
|
556 |
|
557 |
|
@@ -566,6 +588,7 @@ class Manager {
|
|
566 |
* @param string $path Plugin file.
|
567 |
* @param array $params Params to requests.
|
568 |
* @return \Aventura\Wprss\Core\Licensing\Plugin\UpdaterInterface
|
|
|
569 |
*/
|
570 |
public function newUpdater($url, $path, $params = array()) {
|
571 |
// Get the updater class
|
@@ -580,7 +603,7 @@ class Manager {
|
|
580 |
|
581 |
$updater = new $updaterClass($url, $path, $params);
|
582 |
if ( !($updater instanceof Plugin\UpdaterInterface) ) {
|
583 |
-
throw new
|
584 |
}
|
585 |
|
586 |
return $updater;
|
1 |
<?php
|
2 |
|
3 |
namespace Aventura\Wprss\Core\Licensing;
|
4 |
+
|
5 |
use \Aventura\Wprss\Core\Licensing\License\Status;
|
6 |
+
use \Aventura\Wprss\Core\Licensing\Api\RequestException;
|
7 |
+
use \Aventura\Wprss\Core\Licensing\Api\ResponseException;
|
8 |
+
use \Aventura\Wprss\Core\Licensing\Plugin\UpdaterException;
|
9 |
|
10 |
/**
|
11 |
* Manager class for license handling.
|
434 |
|
435 |
// Addon Uppercase ID
|
436 |
$addonUid = strtoupper( $addonId );
|
437 |
+
// Prepare constants names
|
438 |
+
$itemNameConstant = sprintf( 'WPRSS_%s_SL_ITEM_NAME', $addonUid );
|
439 |
+
$storeUrlConstant = sprintf( 'WPRSS_%s_SL_STORE_URL', $addonUid );
|
440 |
+
// Check for existence of constants
|
441 |
+
if ( !defined($itemNameConstant) || !defined($storeUrlConstant) ) {
|
442 |
+
return null;
|
443 |
+
}
|
444 |
+
// Get constant values
|
445 |
+
$itemName = constant( $itemNameConstant );
|
446 |
+
$storeUrl = constant( $storeUrlConstant );
|
447 |
|
448 |
try {
|
449 |
$licenseData = $this->api($storeUrl, array(
|
451 |
'license' => $license,
|
452 |
'item_name' => $itemName,
|
453 |
));
|
454 |
+
}
|
455 |
+
catch ( RequestException $e ) {
|
456 |
wprss_log( sprintf( 'Could not retrieve licensing data from "%1$s": %2$s', $storeUrl, $e->getMessage() ), __FUNCTION__, WPRSS_LOG_LEVEL_WARNING );
|
457 |
return $license->getStatus();
|
458 |
}
|
459 |
+
catch ( ResponseException $e ) {
|
460 |
+
wprss_log( sprintf( 'Received invalid licensing data from "%1$s": %2$s', $storeUrl, $e->getMessage() ), __FUNCTION__, WPRSS_LOG_LEVEL_WARNING );
|
461 |
+
return $license->getStatus();
|
462 |
+
}
|
463 |
|
464 |
// Update the DB option
|
465 |
$license->setStatus( $licenseData->license );
|
485 |
* 'item_name' are required for a successful call. 'license' can also be
|
486 |
* an instance of {@link Aventura\Wprss\Core\Licensing\License}.
|
487 |
* @return object License data as properties of an stdClass instance.
|
488 |
+
* @throws RequestException If request fails or a response is not received.
|
489 |
+
* @throws ResponseException If the response is empty or cannot be decoded.
|
490 |
*/
|
491 |
public function api($storeUrl, $params) {
|
492 |
$defaultParams = array(
|
510 |
|
511 |
// Request failed
|
512 |
if ( is_wp_error( $response ) ) {
|
513 |
+
throw new RequestException( $response->get_error_message() );
|
514 |
}
|
515 |
|
516 |
$body = wp_remote_retrieve_body( $response );
|
517 |
if ( empty( $body ) ) {
|
518 |
+
throw new ResponseException( 'Response body is empty' );
|
519 |
}
|
520 |
|
521 |
if ( ($licenseData = json_decode( $body )) === null ) {
|
522 |
+
throw new ResponseException( sprintf( 'Response body could not be decoded: %1$s', $body ) );
|
523 |
}
|
524 |
|
525 |
return $licenseData;
|
557 |
return false;
|
558 |
}
|
559 |
|
560 |
+
try {
|
561 |
+
// Create an updater
|
562 |
+
$updater = $this->newUpdater($storeUrl, $path, array(
|
563 |
+
'version' => $version, // current version number
|
564 |
+
'license' => $license, // license key (used get_option above to retrieve from DB)
|
565 |
+
'item_name' => $itemName, // name of this plugin
|
566 |
+
));
|
567 |
+
|
568 |
+
// Register the updater
|
569 |
+
$this->_setUpdaterInstance($id, $updater);
|
570 |
+
|
571 |
+
// Return true to indicate success
|
572 |
+
return true;
|
573 |
+
} catch ( UpdaterException $e ) {
|
574 |
+
wprss_log( sprintf( 'Could not create new updater:: %1$s', $e->getMessage() ), __FUNCTION__, WPRSS_LOG_LEVEL_WARNING );
|
575 |
+
return false;
|
576 |
+
}
|
577 |
}
|
578 |
|
579 |
|
588 |
* @param string $path Plugin file.
|
589 |
* @param array $params Params to requests.
|
590 |
* @return \Aventura\Wprss\Core\Licensing\Plugin\UpdaterInterface
|
591 |
+
* @throws \Aventura\Wprss\Core\Licensing\Plugin\Updater\InstanceException If the updater instance class is not a valid updater class.
|
592 |
*/
|
593 |
public function newUpdater($url, $path, $params = array()) {
|
594 |
// Get the updater class
|
603 |
|
604 |
$updater = new $updaterClass($url, $path, $params);
|
605 |
if ( !($updater instanceof Plugin\UpdaterInterface) ) {
|
606 |
+
throw new UpdaterException(sprintf('Could not create updater instance: class "%1$s" is not a valid updater', get_class($updater)));
|
607 |
}
|
608 |
|
609 |
return $updater;
|
includes/Aventura/Wprss/Core/Licensing/Plugin/Exception.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Licensing\Plugin;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core\Licensing;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Description of Exception
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
class Exception extends Licensing\Exception
|
13 |
+
{
|
14 |
+
//put your code here
|
15 |
+
}
|
includes/Aventura/Wprss/Core/Licensing/Plugin/UpdaterException.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Licensing\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Thrown when there's an issue with the updater.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
* @see Aventura\Wprss\Core\Licensing\Plugin\UpdaterInterface
|
10 |
+
*/
|
11 |
+
class UpdaterException extends Exception {
|
12 |
+
}
|
includes/Aventura/Wprss/Core/Model/AssetsAbstract.php
ADDED
@@ -0,0 +1,610 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Something that can be used as an assets controller.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
abstract class AssetsAbstract extends Core\Plugin\ComponentAbstract implements AssetsInterface
|
13 |
+
{
|
14 |
+
/** @since 4.8.1 */
|
15 |
+
const HANDLE_PREFIX = '';
|
16 |
+
|
17 |
+
/** @since 4.8.1 */
|
18 |
+
const ASSET_TYPE_STYLE = 'style';
|
19 |
+
/** @since 4.8.1 */
|
20 |
+
const ASSET_TYPE_SCRIPT = 'script';
|
21 |
+
|
22 |
+
/** @since 4.8.1 */
|
23 |
+
protected static $_assetTypes = array(
|
24 |
+
self::ASSET_TYPE_STYLE => self::ASSET_TYPE_STYLE,
|
25 |
+
self::ASSET_TYPE_SCRIPT => self::ASSET_TYPE_SCRIPT
|
26 |
+
);
|
27 |
+
|
28 |
+
/** @since 4.8.1 */
|
29 |
+
protected $_assets = array();
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @since 4.8.1
|
33 |
+
*/
|
34 |
+
public function hook()
|
35 |
+
{
|
36 |
+
$this->_hook();
|
37 |
+
parent::hook();
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @since 4.8.1
|
42 |
+
*/
|
43 |
+
protected function _hook() {
|
44 |
+
$this->on('!wp_enqueue_scripts', array($this, 'enqueuePublicStyles'));
|
45 |
+
$this->on('!wp_enqueue_scripts', array($this, 'enqueuePublicScripts'));
|
46 |
+
$this->on('!admin_enqueue_scripts', array($this, 'enqueueAdminStyles'));
|
47 |
+
$this->on('!admin_enqueue_scripts', array($this, 'enqueueAdminScripts'));
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Regisger a stylesheet.
|
53 |
+
*
|
54 |
+
* @since 4.8.1
|
55 |
+
* @see wp_enqueue_style()
|
56 |
+
* @param string $handle The resource handle of the style.
|
57 |
+
* @param string $url The stylesheet URL. If not absolute will be relative to the base CSS URI;
|
58 |
+
* See {@see getCssUri()}.
|
59 |
+
* @param array|null $dependencies One or many handles of other resources, on which this style depends.
|
60 |
+
* @param string|null $version The version number of this stylesheet. Changing version number will cause the
|
61 |
+
* user agents to flush the resource's cache.
|
62 |
+
* Default: The version of the plugin, to which this component belongs.
|
63 |
+
* @param string|null $media The media, on which this stylesheed should have effect.
|
64 |
+
* Default: 'all'.
|
65 |
+
* @return AssetsAbstract
|
66 |
+
*/
|
67 |
+
protected function _registerStyle($handle, $url, $dependencies = null, $version = null, $media = null, $allowOverwrite = false)
|
68 |
+
{
|
69 |
+
return $this->register(self::ASSET_TYPE_STYLE, array(
|
70 |
+
'handle' => $handle,
|
71 |
+
'version' => $version,
|
72 |
+
'uri' => $url,
|
73 |
+
'media' => $media
|
74 |
+
), $dependencies, $allowOverwrite);
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Register a script.
|
79 |
+
*
|
80 |
+
* @since 4.8.1
|
81 |
+
* @see wp_enqueue_script()
|
82 |
+
* @param string $handle The resource handle of the script.
|
83 |
+
* @param string $url The script URL. If not absolute will be relative to the base JS URI;
|
84 |
+
* See {@see getJsUri()}.
|
85 |
+
* @param array|null $dependencies One or many handles of other resources, on which this script depends.
|
86 |
+
* @param string|null $version The version number of this script. Changing version number will cause the
|
87 |
+
* user agents to flush the resource's cache.
|
88 |
+
* Default: The version of the plugin, to which this component belongs.
|
89 |
+
* @param bool|null $inFooter Whether or not the script should be in the footer.
|
90 |
+
* @param bool $allowOverwrite Whether or not the asset should still be enqueued even if this handle is already registered.
|
91 |
+
* @return AssetsAbstract
|
92 |
+
*/
|
93 |
+
protected function _registerScript($handle, $url, $dependencies = null, $version = null, $inFooter = false, $allowOverwrite = false)
|
94 |
+
{
|
95 |
+
return $this->register(self::ASSET_TYPE_SCRIPT, array(
|
96 |
+
'handle' => $handle,
|
97 |
+
'version' => $version,
|
98 |
+
'uri' => $url,
|
99 |
+
'in_footer' => $inFooter
|
100 |
+
), $dependencies, $allowOverwrite);
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Registers an asset.
|
105 |
+
*
|
106 |
+
* @since 4.8.1
|
107 |
+
* @param string $type The type of the asset.
|
108 |
+
* @param array $data Data of the asset. Following keys supported:
|
109 |
+
* 'handle'*, 'uri'*, 'version', 'in_footer' (SCRIPT), 'media'(STYLE)
|
110 |
+
* The 'handle' value will be prefixed, unless overridden/
|
111 |
+
* The 'uri' value will be made absolute, unless already absolute.
|
112 |
+
* @param array|null $dependencies Handles of asset that this asset depends on, if any.
|
113 |
+
* @throws Core\Exception If invalid 'type' value, or 'handle' or 'uri' not supplied.
|
114 |
+
*/
|
115 |
+
public function register($type, $data, $dependencies = null, $allowOverwrite = false)
|
116 |
+
{
|
117 |
+
$type = trim($type);
|
118 |
+
if (!static::hasAssetType($type)) {
|
119 |
+
throw $this->exception(array('Could not register asset of type "%1$s": Type is invalid, please use one of [%2$s]',
|
120 |
+
$type,
|
121 |
+
implode(', ', static::getAssetTypes())));
|
122 |
+
}
|
123 |
+
|
124 |
+
// Default version
|
125 |
+
if (is_null($data['version'])) {
|
126 |
+
$data['version'] = $this->getPlugin()->getVersion();
|
127 |
+
}
|
128 |
+
// Default dependencies
|
129 |
+
if (is_null($dependencies)) {
|
130 |
+
$dependencies = array();
|
131 |
+
}
|
132 |
+
$dependencies = (array)$dependencies;
|
133 |
+
// Must provide handle
|
134 |
+
if (!isset($data['handle'])) {
|
135 |
+
throw $this->exception(array('Could not register asset of type "%1$s": Handle must be provided', $type));
|
136 |
+
}
|
137 |
+
// Must provide uri
|
138 |
+
if (!isset($data['uri'])) {
|
139 |
+
throw $this->exception(array('Could not register asset "%2$s" of type "%1$s": URI must be provided', $type, $data['handle']));
|
140 |
+
}
|
141 |
+
|
142 |
+
// Normalizing handle
|
143 |
+
if (!static::stringHadPrefix($data['handle'])) {
|
144 |
+
$data['handle'] = $this->getHandlePrefix($data['handle']);
|
145 |
+
}
|
146 |
+
// Normalizing stylesheet
|
147 |
+
if (!static::isUriAbsolute($data['uri'])) {
|
148 |
+
switch ($type) {
|
149 |
+
case static::ASSET_TYPE_STYLE:
|
150 |
+
$data['uri'] = $this->getCssUri($data['uri']);
|
151 |
+
break;
|
152 |
+
|
153 |
+
case static::ASSET_TYPE_SCRIPT:
|
154 |
+
$data['uri'] = $this->getJsUri($data['uri']);
|
155 |
+
break;
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
return $this->_register($type, $data, $dependencies, $allowOverwrite);
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Registers an asset.
|
164 |
+
*
|
165 |
+
* @since 4.8.1
|
166 |
+
* @param string $type The type of the asset.
|
167 |
+
* @param array $data Data of the asset. Following keys supported:
|
168 |
+
* 'handle'*, 'uri'*, 'version', 'in_footer' (SCRIPT), 'media'(STYLE)
|
169 |
+
* The 'handle' value will be prefixed, unless overridden/
|
170 |
+
* The 'uri' value will be made absolute, unless already absolute.
|
171 |
+
* @param array|null $dependencies Handles of asset that this asset depends on, if any.
|
172 |
+
* @throws Core\Exception If invalid 'type' value, or 'handle' or 'uri' not supplied.
|
173 |
+
*/
|
174 |
+
protected function _register($type, $data, array $dependencies, $allowOverwrite = false)
|
175 |
+
{
|
176 |
+
switch ($type) {
|
177 |
+
case static::ASSET_TYPE_SCRIPT:
|
178 |
+
// Default value
|
179 |
+
if (!isset($data['in_footer'])) {
|
180 |
+
$data['in_footer'] = false;
|
181 |
+
}
|
182 |
+
|
183 |
+
return $this->_addAsset($type, $data, $dependencies, $allowOverwrite);
|
184 |
+
break;
|
185 |
+
|
186 |
+
case static::ASSET_TYPE_STYLE:
|
187 |
+
// Default value
|
188 |
+
if (!isset($data['media'])) {
|
189 |
+
$data['media'] = 'all';
|
190 |
+
}
|
191 |
+
|
192 |
+
return $this->_addAsset($type, $data, $dependencies, $allowOverwrite);
|
193 |
+
break;
|
194 |
+
}
|
195 |
+
|
196 |
+
return null;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Add an asset to asset list.
|
201 |
+
*
|
202 |
+
* @param string $type The type of the asset.
|
203 |
+
* @param array $data The asset data.
|
204 |
+
* @param array $dependencies The dependencies of the asset, if any.
|
205 |
+
* @param bool $allowOverride If true, and the handle already registered, it will be replaced.
|
206 |
+
* @return string The handle of the added asset.
|
207 |
+
*/
|
208 |
+
protected function _addAsset($type, $data, array $dependencies, $allowOverride = false)
|
209 |
+
{
|
210 |
+
if (isset($this->_assets[$type]) && $allowOverride) {
|
211 |
+
return null;
|
212 |
+
}
|
213 |
+
|
214 |
+
$handle = isset($data['handle']) ? $data['handle'] : $this->_getUniqueHandle();
|
215 |
+
$data['type'] = $type;
|
216 |
+
$data['dependencies'] = $dependencies;
|
217 |
+
$this->_assets[$handle] = $data;
|
218 |
+
return $handle;
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Generate a unique asset handle.
|
223 |
+
*
|
224 |
+
* @since 4.8.1
|
225 |
+
* @return string A unique, prefixed asset handle.
|
226 |
+
*/
|
227 |
+
protected function _getUniqueHandle($uri = null)
|
228 |
+
{
|
229 |
+
if (is_null($uri)) {
|
230 |
+
return uniqid($this->getHandlePrefix(), true);
|
231 |
+
}
|
232 |
+
|
233 |
+
return $this->getHandlePrefix(md5($uri));
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Retrieve asset data by handle.
|
238 |
+
*
|
239 |
+
* @since 4.8.1
|
240 |
+
* @param string $handle The handle of the asset to get.
|
241 |
+
* @return array The asset data if exists, null otherwise.
|
242 |
+
*/
|
243 |
+
public function getAsset($handle)
|
244 |
+
{
|
245 |
+
return $this->hasAsset($handle) ? $this->_assets[$handle] : null;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Get all registered assets.
|
250 |
+
*
|
251 |
+
* @since 4.8.1
|
252 |
+
* @return array All assets, by handle.
|
253 |
+
*/
|
254 |
+
public function getAssets() {
|
255 |
+
return $this->_assets;
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Whether or not an asset is registered.
|
260 |
+
*
|
261 |
+
* @since 4.8.1
|
262 |
+
* @param string $handle An asset handle.
|
263 |
+
* @return bool True if asset with specified handle exists; false otherwise.
|
264 |
+
*/
|
265 |
+
public function hasAsset($handle)
|
266 |
+
{
|
267 |
+
return isset($this->_assets[$handle]);
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Register an asset.
|
272 |
+
*
|
273 |
+
* @since 4.8.1
|
274 |
+
* @param array $asset An array with asset data.
|
275 |
+
* @return bool True if registered, false otherwise.
|
276 |
+
*/
|
277 |
+
protected function _registerAsset($asset)
|
278 |
+
{
|
279 |
+
|
280 |
+
$type = $asset['type'];
|
281 |
+
switch ($type) {
|
282 |
+
case static::ASSET_TYPE_SCRIPT:
|
283 |
+
wp_register_script(
|
284 |
+
(string)$asset['handle'],
|
285 |
+
(string)$asset['uri'],
|
286 |
+
(array)$asset['dependencies'],
|
287 |
+
(string)$asset['version'],
|
288 |
+
(bool)$asset['in_footer']
|
289 |
+
);
|
290 |
+
return true;
|
291 |
+
break;
|
292 |
+
|
293 |
+
case static::ASSET_TYPE_STYLE:
|
294 |
+
wp_register_style(
|
295 |
+
(string)$asset['handle'],
|
296 |
+
(string)$asset['uri'],
|
297 |
+
(array)$asset['dependencies'],
|
298 |
+
(string)$asset['version'],
|
299 |
+
(string)$asset['media']
|
300 |
+
);
|
301 |
+
return true;
|
302 |
+
break;
|
303 |
+
}
|
304 |
+
|
305 |
+
return false;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Enqueue an asset by handle.
|
310 |
+
*
|
311 |
+
* @since 4.8.1
|
312 |
+
* @param string $asset The asset handle.
|
313 |
+
* @return bool True if enqueued, false otherwise.
|
314 |
+
* @throws Core\Exception If no handle provided, or no asset registered for handle.
|
315 |
+
*/
|
316 |
+
protected function _enqueueAsset($asset)
|
317 |
+
{
|
318 |
+
if(!is_string($asset)) {
|
319 |
+
throw $this->exception('Cannot enqueue asset: An asset handle must be provided');
|
320 |
+
}
|
321 |
+
|
322 |
+
if (!($asset = $this->getAsset($asset))) {
|
323 |
+
throw $this->exception(array('Could not enqueue asset "%1$s": No asset registered with that handle'));
|
324 |
+
}
|
325 |
+
$type = $asset['type'];
|
326 |
+
|
327 |
+
switch ($type) {
|
328 |
+
case static::ASSET_TYPE_SCRIPT:
|
329 |
+
wp_enqueue_script(
|
330 |
+
(string)$asset['handle'],
|
331 |
+
(string)$asset['uri'],
|
332 |
+
(array)$asset['dependencies'],
|
333 |
+
(string)$asset['version'],
|
334 |
+
(bool)$asset['in_footer']
|
335 |
+
);
|
336 |
+
return true;
|
337 |
+
break;
|
338 |
+
|
339 |
+
case static::ASSET_TYPE_STYLE:
|
340 |
+
wp_enqueue_style(
|
341 |
+
(string)$asset['handle'],
|
342 |
+
(string)$asset['uri'],
|
343 |
+
(array)$asset['dependencies'],
|
344 |
+
(string)$asset['version'],
|
345 |
+
(string)$asset['media']
|
346 |
+
);
|
347 |
+
return true;
|
348 |
+
break;
|
349 |
+
}
|
350 |
+
|
351 |
+
return false;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Register a stylesheet.
|
356 |
+
*
|
357 |
+
* @since 4.8.1
|
358 |
+
* @param string $handle The unique asset handle.
|
359 |
+
* @param string $uri The URI of the asset. If relative, it will be appended to the value of {@see getCssUri()}.
|
360 |
+
* @param array|null $dependencies List of dependencies for the assed. If null, empty array will be used.
|
361 |
+
* @param string|null $version The version of the asset. If null, the plugin version will be used.
|
362 |
+
* @param string|null $media The CSS media type.
|
363 |
+
* If null, 'all' will be used.
|
364 |
+
* @param bool|null $allowOverwrite If true, and the handle already exists, it will be overwritten.
|
365 |
+
* @return string|null The asset handle if regisered; otherwise null.
|
366 |
+
*/
|
367 |
+
public function registerStyle($handle, $uri, $dependencies = null, $version = null, $media = null, $allowOverwrite = false)
|
368 |
+
{
|
369 |
+
return $this->_registerStyle($handle, $uri, $dependencies, $version, $media, $allowOverwrite);
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
* Enqueue a registered style by handle.
|
374 |
+
*
|
375 |
+
* @since 4.8.1
|
376 |
+
* @param string $handle The handle of the style to enqueue.
|
377 |
+
* @return AssetsAbstract This instance.
|
378 |
+
* @throws Core\Exception If the handle isn't registered, the handle type is not registered or is not of a style.
|
379 |
+
*/
|
380 |
+
public function enqueueStyle($handle)
|
381 |
+
{
|
382 |
+
// Normalizing handle
|
383 |
+
if (!static::stringHadPrefix($handle)) {
|
384 |
+
$handle = $this->getHandlePrefix($handle);
|
385 |
+
}
|
386 |
+
if (!($asset = $this->getAsset($handle))) {
|
387 |
+
throw $this->exception(array('Could not enqueue script "%1$s": Register the script first', $handle));
|
388 |
+
}
|
389 |
+
if (!$this->hasAssetType($asset['type'])) {
|
390 |
+
throw $this->exception(array('Could not enqueue style "%1$s": "%2$s" is not a registered asset type', $handle, $asset['type']));
|
391 |
+
}
|
392 |
+
if ($asset['type'] !== static::ASSET_TYPE_STYLE) {
|
393 |
+
throw $this->exception(array('Could not enqueue style "%1$s": "%2$s" is not a style type', $handle, $asset['type']));
|
394 |
+
}
|
395 |
+
$this->_enqueueAsset($handle);
|
396 |
+
|
397 |
+
return $this;
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Register a script.
|
402 |
+
*
|
403 |
+
* @since 4.8.1
|
404 |
+
* @param string $handle The unique asset handle.
|
405 |
+
* @param string $uri The URI of the asset. If relative, it will be appended to the value of {@see getJSUri()}.
|
406 |
+
* @param array|null $dependencies List of dependencies for the assed. If null, empty array will be used.
|
407 |
+
* @param string|null $version The version of the asset. If null, the plugin version will be used.
|
408 |
+
* @param bool $inFooter Whether or not the script should go in the footer.
|
409 |
+
* @param bool|null $allowOverwrite If true, and the handle already exists, it will be overwritten.
|
410 |
+
* @return string|null The asset handle if regisered; otherwise null.
|
411 |
+
*/
|
412 |
+
public function registerScript($handle, $uri, $dependencies = null, $version = null, $inFooter = false, $allowOverwrite = false)
|
413 |
+
{
|
414 |
+
$this->_registerScript($handle, $uri, $dependencies, $version, $inFooter, $allowOverwrite);
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Enqueue a registered script by handle.
|
419 |
+
*
|
420 |
+
* @since 4.8.1
|
421 |
+
* @param string $handle The handle of the script to enqueue.
|
422 |
+
* @return AssetsAbstract This instance.
|
423 |
+
* @throws Core\Exception If the handle isn't registered, the handle type is not registered or is not of a script.
|
424 |
+
*/
|
425 |
+
public function enqueueScript($handle)
|
426 |
+
{
|
427 |
+
// Normalizing handle
|
428 |
+
if (!static::stringHadPrefix($handle)) {
|
429 |
+
$handle = $this->getHandlePrefix($handle);
|
430 |
+
}
|
431 |
+
if (!($asset = $this->getAsset($handle))) {
|
432 |
+
throw $this->exception(array('Could not enqueue script "%1$s": Register the script first', $handle));
|
433 |
+
}
|
434 |
+
if (!$this->hasAssetType($asset['type'])) {
|
435 |
+
throw $this->exception(array('Could not enqueue script "%1$s": "%2$s" is not a registered asset type', $handle, $asset['type']));
|
436 |
+
}
|
437 |
+
if ($asset['type'] !== static::ASSET_TYPE_SCRIPT) {
|
438 |
+
throw $this->exception(array('Could not enqueue style "%1$s": "%2$s" is not a script type', $handle, $asset['type']));
|
439 |
+
}
|
440 |
+
$this->_enqueueAsset($handle);
|
441 |
+
|
442 |
+
return $this;
|
443 |
+
}
|
444 |
+
|
445 |
+
/**
|
446 |
+
* Get all asset types of this class.
|
447 |
+
*
|
448 |
+
* @since 4.8.1
|
449 |
+
* @return array The asset type, where keys are the type code.
|
450 |
+
*/
|
451 |
+
public static function getAssetTypes()
|
452 |
+
{
|
453 |
+
return static::$_assetTypes;
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Whether or not an asset type exists.
|
458 |
+
*
|
459 |
+
* @since 4.8.1
|
460 |
+
* @param string $type The asset type.
|
461 |
+
* @return bool True if exists; false otherwise.
|
462 |
+
*/
|
463 |
+
public static function hasAssetType($type)
|
464 |
+
{
|
465 |
+
$types = static::getAssetTypes();
|
466 |
+
return isset($types[$type]);
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* Gets the optionally suffixed prefix for resource handles configured for this instance.
|
471 |
+
*
|
472 |
+
* A resource handle is a unique ID that identifies resources enqueued with functions such as `wp_enqueue_script()`
|
473 |
+
* and `wp_enqueue_style()`.
|
474 |
+
*
|
475 |
+
* @since 4.8.1
|
476 |
+
* @param string|null $handle If speficied, the prefix will be suffixed with this.
|
477 |
+
* @return string|null The prefix for resource handles that is configured for this instance, optionally suffixed
|
478 |
+
* with $handle.
|
479 |
+
*/
|
480 |
+
public function getHandlePrefix($handle = null)
|
481 |
+
{
|
482 |
+
$prefix = $this->_getHandlePrefix();
|
483 |
+
return is_null($handle)
|
484 |
+
? $prefix
|
485 |
+
: static::stringHadPrefix($handle) ? $handle : "{$prefix}{$handle}";
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Gets the prefix for resource handles configured for this instance.
|
490 |
+
*
|
491 |
+
* A resource handle is a unique ID that identifies resources enqueued with functions such as `wp_enqueue_script()`
|
492 |
+
* and `wp_enqueue_style()`.
|
493 |
+
*
|
494 |
+
* If the 'handle_prefix' data member is not set, falls back to the `HANDLE_PREFIX` class constant, then to `null`.
|
495 |
+
*
|
496 |
+
* @since 4.8.1
|
497 |
+
* @return string|null The prefix for resource handles that is configured for this instance.
|
498 |
+
*/
|
499 |
+
public function _getHandlePrefix()
|
500 |
+
{
|
501 |
+
$pluginCode = $this->getPlugin()->getCode();
|
502 |
+
return $this->_getDataOrConst('handle_prefix', $pluginCode ? sprintf('%1$s-', $pluginCode) : '');
|
503 |
+
}
|
504 |
+
|
505 |
+
/**
|
506 |
+
* Gets and optionally suffixes the base CSS URI for this instance.
|
507 |
+
*
|
508 |
+
* @since 4.8.1
|
509 |
+
* @param string|null $path If specified and not null, the base CSS UR will be suffixed with this.
|
510 |
+
* @return string The base CSS URI configured for this instance, optionally suffixed with the $path.
|
511 |
+
*/
|
512 |
+
public function getCssUri($path = null)
|
513 |
+
{
|
514 |
+
$base = untrailingslashit($this->_getDataOrConst('css_uri'));
|
515 |
+
return is_null($path)
|
516 |
+
? $base
|
517 |
+
: "{$base}/{$path}";
|
518 |
+
}
|
519 |
+
|
520 |
+
/**
|
521 |
+
* Gets and optionally suffixes the base JS URI for this instance.
|
522 |
+
*
|
523 |
+
* @since 4.8.1
|
524 |
+
* @param string|null $path If specified and not null, the base JS UR will be suffixed with this.
|
525 |
+
* @return string The base JS URI configured for this instance, optionally suffixed with the $path.
|
526 |
+
*/
|
527 |
+
public function getJsUri($path = null)
|
528 |
+
{
|
529 |
+
$base = untrailingslashit($this->_getDataOrConst('js_uri'));
|
530 |
+
return is_null($path)
|
531 |
+
? $base
|
532 |
+
: "{$base}/{$path}";
|
533 |
+
}
|
534 |
+
|
535 |
+
/**
|
536 |
+
* Gets the base CSS URI configured for this instance.
|
537 |
+
*
|
538 |
+
* If the 'css_uri' data member is not set, falls back to the `CSS_URL` class constant, then to `null`.
|
539 |
+
*
|
540 |
+
* @since 4.8.1
|
541 |
+
* @return string|null The base CSS URI configured for this instance.
|
542 |
+
*/
|
543 |
+
protected function _getCssUri()
|
544 |
+
{
|
545 |
+
// Allowing override via data
|
546 |
+
$key = 'css_uri';
|
547 |
+
if ($this->hasData($key)) {
|
548 |
+
return $this->getData($key);
|
549 |
+
}
|
550 |
+
// Falling back to constant
|
551 |
+
$class = get_class($this);
|
552 |
+
$const = "{$class}::CSS_URI";
|
553 |
+
if (defined($const)) {
|
554 |
+
return constant($const);
|
555 |
+
}
|
556 |
+
|
557 |
+
return null;
|
558 |
+
}
|
559 |
+
|
560 |
+
/**
|
561 |
+
* Checks if a URI is absolute.
|
562 |
+
*
|
563 |
+
* @since 4.8.1
|
564 |
+
* @see uri_is_absolute()
|
565 |
+
*/
|
566 |
+
public static function isUriAbsolute($uri)
|
567 |
+
{
|
568 |
+
return uri_is_absolute($uri);
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* {@inheritdoc}
|
573 |
+
*
|
574 |
+
* @since 4.8.1
|
575 |
+
*/
|
576 |
+
public function enqueuePublicStyles()
|
577 |
+
{
|
578 |
+
return $this;
|
579 |
+
}
|
580 |
+
|
581 |
+
/**
|
582 |
+
* {@inheritdoc}
|
583 |
+
*
|
584 |
+
* @since 4.8.1
|
585 |
+
*/
|
586 |
+
public function enqueuePublicScripts()
|
587 |
+
{
|
588 |
+
return $this;
|
589 |
+
}
|
590 |
+
|
591 |
+
/**
|
592 |
+
* {@inheritdoc}
|
593 |
+
*
|
594 |
+
* @since 4.8.1
|
595 |
+
*/
|
596 |
+
public function enqueueAdminStyles()
|
597 |
+
{
|
598 |
+
return $this;
|
599 |
+
}
|
600 |
+
|
601 |
+
/**
|
602 |
+
* {@inheritdoc}
|
603 |
+
*
|
604 |
+
* @since 4.8.1
|
605 |
+
*/
|
606 |
+
public function enqueueAdminScripts()
|
607 |
+
{
|
608 |
+
return $this;
|
609 |
+
}
|
610 |
+
}
|
includes/Aventura/Wprss/Core/Model/AssetsInterface.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Something that can be used as an assets controller.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface AssetsInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Enqueues the styles for the front-end.
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
*/
|
17 |
+
public function enqueuePublicStyles();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Enqueues the scripts for the front-end.
|
21 |
+
*
|
22 |
+
* @since 4.8.1
|
23 |
+
*/
|
24 |
+
public function enqueuePublicScripts();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Enqueues the styles for the front-end.
|
28 |
+
*
|
29 |
+
* @since 4.8.1
|
30 |
+
*/
|
31 |
+
public function enqueueAdminStyles();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Enqueues the scripts for the front-end.
|
35 |
+
*
|
36 |
+
* @since 4.8.1
|
37 |
+
*/
|
38 |
+
public function enqueueAdminScripts();
|
39 |
+
}
|
includes/Aventura/Wprss/Core/Model/Command.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* A single command.
|
7 |
+
*
|
8 |
+
* Possible to instantiate and use right away.
|
9 |
+
*
|
10 |
+
* @since [*next-version]
|
11 |
+
*/
|
12 |
+
class Command extends CommandAbstract
|
13 |
+
{
|
14 |
+
|
15 |
+
}
|
includes/Aventura/Wprss/Core/Model/CommandAbstract.php
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Common functionality for all commands.
|
7 |
+
*
|
8 |
+
* @since [*next-version]
|
9 |
+
*/
|
10 |
+
abstract class CommandAbstract extends ModelAbstract implements CommandInterface
|
11 |
+
{
|
12 |
+
protected $_callable;
|
13 |
+
protected $_args = array();
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @since 4.8.1
|
18 |
+
* @param callable $data The {@link set_function() function} to give to the command.
|
19 |
+
*/
|
20 |
+
public function __construct( $data = array() )
|
21 |
+
{
|
22 |
+
if (is_callable($data, true)) {
|
23 |
+
$data = array('function' => $data);
|
24 |
+
}
|
25 |
+
|
26 |
+
if (isset($data['function'])) {
|
27 |
+
$this->setFunction($data['function']);
|
28 |
+
unset($data['function']);
|
29 |
+
}
|
30 |
+
|
31 |
+
if (isset($data['args'])) {
|
32 |
+
$this->setArgs($data['args']);
|
33 |
+
unset($data['args']);
|
34 |
+
}
|
35 |
+
|
36 |
+
parent::__construct($data);
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Sets the function to be called with this command.
|
42 |
+
*
|
43 |
+
* @since 4.8.1
|
44 |
+
* @param callable $function The function or method to be called.
|
45 |
+
* @return CommandAbstract This instance.
|
46 |
+
* @throws CommandException If passed function is not a valid callable.
|
47 |
+
*/
|
48 |
+
public function setFunction( $function ) {
|
49 |
+
if ( !is_callable( $function, true ) )
|
50 |
+
throw $this->exception( 'Could not set function: function is not a valid callable', array(__NAMESPACE__, 'CommandException') );
|
51 |
+
|
52 |
+
$this->_callable = $function;
|
53 |
+
return $this;
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Sets the argument or arguments for this command.
|
59 |
+
*
|
60 |
+
* If index is null or omitted, all arguments will be set to the value of $args.
|
61 |
+
* If in this case $args is not an array, args will be an array where $args is
|
62 |
+
* the only element.
|
63 |
+
* In any case, the indexes of $args do not matter, but the order does.
|
64 |
+
*
|
65 |
+
* @since 4.8.1
|
66 |
+
* @param array $args The argument or arguments to set for this command.
|
67 |
+
* @param int $index The index, at which to set the argument.
|
68 |
+
* @return CommandAbstract This instance.
|
69 |
+
*/
|
70 |
+
public function setArgs( $args, $index = null ) {
|
71 |
+
if ( is_null( $index ) ) {
|
72 |
+
$this->_args = array_values( (array) $args );
|
73 |
+
return $this;
|
74 |
+
}
|
75 |
+
|
76 |
+
$index = (int) $index;
|
77 |
+
$this->_args[ $index ] = $args;
|
78 |
+
|
79 |
+
return $this;
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @since 4.8.1
|
85 |
+
* @return callable The function of the command.
|
86 |
+
*/
|
87 |
+
public function getFunction() {
|
88 |
+
return $this->_callable;
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Gets the argument or arguments for this command.
|
94 |
+
*
|
95 |
+
* @since 4.8.1
|
96 |
+
* @param int|null $index The index of the argument to return.
|
97 |
+
* @return array|mixed|null The argument, or arguments, or null if not found.
|
98 |
+
*/
|
99 |
+
public function getArgs( $index = null ) {
|
100 |
+
if ( is_null( $index ) )
|
101 |
+
return $this->_args;
|
102 |
+
|
103 |
+
$index = (int) $index;
|
104 |
+
return isset( $this->_args[ $index ] ) ? $this->_args[ $index ] : null;
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Calls the function of this command with the given arguments.
|
110 |
+
*
|
111 |
+
* @since 4.8.1
|
112 |
+
* @param array $args_override A different set of arguments that will override the original.
|
113 |
+
* @return mixed The return value of the function of the command.
|
114 |
+
* @throws CommandException If the function of the command is not callable.
|
115 |
+
*/
|
116 |
+
public function call($args_override = array()) {
|
117 |
+
$args = $this->getArgs();
|
118 |
+
$args = array_merge_recursive_distinct( $args, $args_override );
|
119 |
+
|
120 |
+
if ( !is_callable( $callable = $this->getFunction() ) )
|
121 |
+
throw $this->exception( 'Could not call function: function must be callable', array(__NAMESPACE__, 'CommandException') );
|
122 |
+
|
123 |
+
$result = call_user_func_array( $callable, $args);
|
124 |
+
return $result;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Allows instances of this class and its descendants to be called like a function.
|
129 |
+
*
|
130 |
+
* @since 4.8.1
|
131 |
+
* @return type
|
132 |
+
*/
|
133 |
+
public function __invoke()
|
134 |
+
{
|
135 |
+
$args = func_get_args();
|
136 |
+
return $this->call($args);
|
137 |
+
}
|
138 |
+
}
|
includes/Aventura/Wprss/Core/Model/CommandException.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* An exception that occurs when doing something related to a command.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
class CommandException extends Core\Exception
|
13 |
+
{
|
14 |
+
}
|
includes/Aventura/Wprss/Core/Model/CommandInterface.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* An interface of something that can be a command.
|
7 |
+
*
|
8 |
+
* @since [*next-version]
|
9 |
+
*/
|
10 |
+
interface CommandInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Makes it possible to invoke an instance of the implementing class
|
14 |
+
* as if it was a function.
|
15 |
+
*
|
16 |
+
* @since 4.8.1
|
17 |
+
* @return mixed The result of the call
|
18 |
+
*/
|
19 |
+
public function __invoke();
|
20 |
+
}
|
includes/Aventura/Wprss/Core/Model/Event/Event.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model\Event;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @since 4.8.1
|
7 |
+
*/
|
8 |
+
class Event extends EventAbstract
|
9 |
+
{
|
10 |
+
|
11 |
+
}
|
includes/Aventura/Wprss/Core/Model/Event/EventAbstract.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model\Event;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
abstract class EventAbstract extends Core\DataObject implements EventInterface
|
11 |
+
{
|
12 |
+
/** @since 4.8.1 */
|
13 |
+
protected $_name;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @since 4.8.1
|
17 |
+
* @param array|string $data The event's data. Must have a 'name' index.
|
18 |
+
* If string, will be used as 'name'.
|
19 |
+
*/
|
20 |
+
public function __construct($data)
|
21 |
+
{
|
22 |
+
if (!is_array($data)) {
|
23 |
+
$data = array('name' => $data);
|
24 |
+
}
|
25 |
+
|
26 |
+
parent::__construct($data);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @since 4.8.1
|
31 |
+
* @throws Core\Exception If 'name' index is not present.
|
32 |
+
*/
|
33 |
+
protected function _construct()
|
34 |
+
{
|
35 |
+
parent::_construct();
|
36 |
+
|
37 |
+
if (!$this->hasData('name')) {
|
38 |
+
throw new Exception('Could not create event: Name must be specified');
|
39 |
+
}
|
40 |
+
|
41 |
+
$this->_setName($this->getData('name'));
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Get the name of this event
|
46 |
+
*
|
47 |
+
* @since 4.8.1
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function getName()
|
51 |
+
{
|
52 |
+
return $this->_name;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Blocks setting name from outside.
|
57 |
+
*
|
58 |
+
* If used, a notice will be emitted.
|
59 |
+
*
|
60 |
+
* @since 4.8.1
|
61 |
+
* @access protected
|
62 |
+
* @param string $name
|
63 |
+
* @return EventAbstract This instance.
|
64 |
+
*/
|
65 |
+
public function setName($name)
|
66 |
+
{
|
67 |
+
trigger_error('Event name can only be set upon creation', E_USER_NOTICE);
|
68 |
+
return $this;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Set this event's name.
|
73 |
+
*
|
74 |
+
* @since 4.8.1
|
75 |
+
* @param string $name
|
76 |
+
* @return EventAbstract This instance.
|
77 |
+
*/
|
78 |
+
protected function _setName($name)
|
79 |
+
{
|
80 |
+
$this->_name = trim($name);
|
81 |
+
return $this;
|
82 |
+
}
|
83 |
+
}
|
includes/Aventura/Wprss/Core/Model/Event/EventInterface.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model\Event;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @since 4.8.1
|
7 |
+
*/
|
8 |
+
interface EventInterface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Get the event name.
|
12 |
+
*
|
13 |
+
* @since 4.8.1
|
14 |
+
*/
|
15 |
+
public function getName();
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Get event data.
|
19 |
+
*
|
20 |
+
* @since 4.8.1
|
21 |
+
* @param string|null $key All event data, or data at a specific index.\
|
22 |
+
*/
|
23 |
+
public function getData($key = null);
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Set event data.
|
27 |
+
*
|
28 |
+
* @since 4.8.1
|
29 |
+
* @param array|string $key The key to set the value for, or an array of data to replace.
|
30 |
+
* @param mixed|null $value The value to set for the data key.
|
31 |
+
*/
|
32 |
+
public function setData($key, $value = null);
|
33 |
+
}
|
includes/Aventura/Wprss/Core/Model/Event/EventManagerAbstract.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model\Event;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
class EventManagerAbstract extends Core\Plugin\ComponentAbstract implements EventManagerInterface
|
11 |
+
{
|
12 |
+
/** @since 4.8.1 */
|
13 |
+
const DEFAULT_PRIORITY = 10;
|
14 |
+
|
15 |
+
/** @since 4.8.1 */
|
16 |
+
const DEFAULT_ACCEPTED_ARGS = 1;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* The array of actions registered with WordPress.
|
20 |
+
*
|
21 |
+
* @since 4.8.1
|
22 |
+
* @var array $actions The actions registered with WordPress to fire when the plugin loads.
|
23 |
+
*/
|
24 |
+
protected $_events = array();
|
25 |
+
protected $_isRan;
|
26 |
+
|
27 |
+
protected function _construct()
|
28 |
+
{
|
29 |
+
parent::_construct();
|
30 |
+
$this->setIsKeepRecords(true);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Registers an event listener.
|
35 |
+
*
|
36 |
+
* @since 4.8.1
|
37 |
+
* @param string $name The name of the event that a listener is being registered for.
|
38 |
+
* @param callable $listener The listener.
|
39 |
+
* @param int|null $priority The priority at which the listener should be invoked.
|
40 |
+
* Default: {@link EventManagerAbstract::DEFAULT_PRIORITY}.
|
41 |
+
* @param array|null $data
|
42 |
+
* @param int|null $acceptedArgs The number of arguments that should be passed to the listener.
|
43 |
+
* Default: {@link EventManagerAbstract::DEFAULT_ACCEPTED_ARGS}.
|
44 |
+
* You don't really need to specify this with events fired via this class.
|
45 |
+
* @param bool $now Whether or not to add the event right now, now when run().
|
46 |
+
* @return EventManagerAbstract This instance.
|
47 |
+
*/
|
48 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null)
|
49 |
+
{
|
50 |
+
if (is_null($priority)) {
|
51 |
+
$priority = static::DEFAULT_PRIORITY;
|
52 |
+
}
|
53 |
+
if (is_null($acceptedArgs)) {
|
54 |
+
$acceptedArgs = static::DEFAULT_ACCEPTED_ARGS;
|
55 |
+
}
|
56 |
+
if (is_null($data)) {
|
57 |
+
$data = array();
|
58 |
+
}
|
59 |
+
|
60 |
+
$listener = $this->_normalizeCallback($listener);
|
61 |
+
$eventInfo = array(
|
62 |
+
'name' => $name,
|
63 |
+
'listener' => $listener,
|
64 |
+
'args' => $data,
|
65 |
+
'priority' => $priority,
|
66 |
+
'accepted_args' => $acceptedArgs
|
67 |
+
);
|
68 |
+
if ($this->getIsKeepRecords()) {
|
69 |
+
$this->_events[] = $eventInfo;
|
70 |
+
}
|
71 |
+
$this->_register($eventInfo);
|
72 |
+
|
73 |
+
return $name;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Registers an event with the environment.
|
78 |
+
*
|
79 |
+
* @since 4.8.1
|
80 |
+
* @param array $eventInfo Data of the event.
|
81 |
+
* @return EventManagerAbstract This instance.
|
82 |
+
*/
|
83 |
+
protected function _register($eventInfo)
|
84 |
+
{
|
85 |
+
$proxy = function() use ($eventInfo) {
|
86 |
+
$args = func_get_args();
|
87 |
+
|
88 |
+
// Adding registration time arguments
|
89 |
+
$event = isset($args[0]) ? $args[0] : null;
|
90 |
+
$argsOverride = isset($eventInfo['args']) ? $eventInfo['args'] : array();
|
91 |
+
if ($event instanceof EventInterface) {
|
92 |
+
foreach ($argsOverride as $_arg => $_argVal) {
|
93 |
+
if (!$event->hasData($_arg)) {
|
94 |
+
$event->setData($_arg, $_argVal);
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
return call_user_func_array($eventInfo['listener'], $args);
|
100 |
+
};
|
101 |
+
|
102 |
+
add_filter($eventInfo['name'], $proxy, $eventInfo['priority'], $eventInfo['accepted_args']);
|
103 |
+
return $this;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Normalizes a callback.
|
108 |
+
*
|
109 |
+
* @since 4.8.1
|
110 |
+
* @param callable $callback The callback to normalize
|
111 |
+
* @return If array is given, makes sure that the result is a numeric array with correct order of valuesl
|
112 |
+
* Otherwise, returns the callback unmodified.
|
113 |
+
*/
|
114 |
+
protected function _normalizeCallback($callback)
|
115 |
+
{
|
116 |
+
if (is_array($callback)) {
|
117 |
+
$callback = array_values($callback);
|
118 |
+
$component = $callback[0];
|
119 |
+
$callback = $callback[1];
|
120 |
+
$callback = array($component, $callback);
|
121 |
+
}
|
122 |
+
|
123 |
+
return $callback;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* {@inheritdoc}
|
128 |
+
*
|
129 |
+
* @since 4.8.1
|
130 |
+
*/
|
131 |
+
public function event($name, $data = array())
|
132 |
+
{
|
133 |
+
if (is_object($data)) {
|
134 |
+
$data = (array) $data;
|
135 |
+
}
|
136 |
+
$event = $this->_createEvent($name, $data);
|
137 |
+
return $this->_dispatch($event);
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Dispatches the actual event.
|
142 |
+
*
|
143 |
+
* @since 4.8.1
|
144 |
+
* @param EventInterface $event The event to dispatch.
|
145 |
+
* @return mixed The event object, possibly modified.
|
146 |
+
*/
|
147 |
+
protected function _dispatch(EventInterface $event)
|
148 |
+
{
|
149 |
+
return apply_filters($event->getName(), $event);
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Creates a new event.
|
154 |
+
*
|
155 |
+
* @since 4.8.1
|
156 |
+
* @param string $name The name of the event.
|
157 |
+
* @param array $args An array of arguments.
|
158 |
+
* @return EventInterface
|
159 |
+
*/
|
160 |
+
protected function _createEvent($name, $args = array())
|
161 |
+
{
|
162 |
+
$event = new Event($name);
|
163 |
+
foreach($args as $_key => $_val) {
|
164 |
+
$event->setData($_key, $_val);
|
165 |
+
}
|
166 |
+
return $event;
|
167 |
+
}
|
168 |
+
}
|
includes/Aventura/Wprss/Core/Model/Event/EventManagerInterface.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model\Event;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* An interface for something that can manage events.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface EventManagerInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Add an event listener.
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
* @param string $name The name of the event.
|
17 |
+
* @param callable $listener The listener of the event.
|
18 |
+
* @param null|int $priority Priority of the listener. If null, implementation-default will be used.
|
19 |
+
* @param null|int $numArgs Number of arguments to pass to the listener. If null, implementation-default will be used.
|
20 |
+
*/
|
21 |
+
public function on($name, $listener, $args = null, $priority = null, $numArgs = null);
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Raises an event.
|
25 |
+
*
|
26 |
+
* @since 4.8.1
|
27 |
+
* @param string $name Name of the event.
|
28 |
+
* @param array|object $data The event data.
|
29 |
+
* @return EventInterface An event object that is the result of this event.
|
30 |
+
* This object will contain the data passed, and possibly modified.
|
31 |
+
*/
|
32 |
+
public function event($name, $data = array());
|
33 |
+
}
|
includes/Aventura/Wprss/Core/Model/LoggerAbstract.php
ADDED
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
abstract class LoggerAbstract extends Core\Plugin\ComponentAbstract implements LoggerInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Detailed debug information
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
*/
|
17 |
+
const DEBUG = 100;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Interesting events
|
21 |
+
*
|
22 |
+
* Examples: User logs in, SQL logs.
|
23 |
+
*
|
24 |
+
* @since 4.8.1
|
25 |
+
*/
|
26 |
+
const INFO = 200;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Uncommon events
|
30 |
+
*
|
31 |
+
* @since 4.8.1
|
32 |
+
*/
|
33 |
+
const NOTICE = 250;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Exceptional occurrences that are not errors
|
37 |
+
*
|
38 |
+
* Examples: Use of deprecated APIs, poor use of an API,
|
39 |
+
* undesirable things that are not necessarily wrong.
|
40 |
+
*
|
41 |
+
* @since 4.8.1
|
42 |
+
*/
|
43 |
+
const WARNING = 300;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Runtime errors
|
47 |
+
*
|
48 |
+
* @since 4.8.1
|
49 |
+
*/
|
50 |
+
const ERROR = 400;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Critical conditions
|
54 |
+
*
|
55 |
+
* Example: Application component unavailable, unexpected exception.
|
56 |
+
*
|
57 |
+
* @since 4.8.1
|
58 |
+
*/
|
59 |
+
const CRITICAL = 500;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Action must be taken immediately
|
63 |
+
*
|
64 |
+
* Example: Entire website down, database unavailable, etc.
|
65 |
+
* This should trigger the SMS alerts and wake you up.
|
66 |
+
*
|
67 |
+
* @since 4.8.1
|
68 |
+
*/
|
69 |
+
const ALERT = 550;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Urgent alert.
|
73 |
+
*
|
74 |
+
* @since 4.8.1
|
75 |
+
*/
|
76 |
+
const EMERGENCY = 600;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Logging levels from syslog protocol defined in RFC 5424
|
80 |
+
*
|
81 |
+
* @since 4.8.1
|
82 |
+
* @var array $levels Logging levels
|
83 |
+
*/
|
84 |
+
protected static $_levels = array(
|
85 |
+
self::DEBUG => 'DEBUG',
|
86 |
+
self::INFO => 'INFO',
|
87 |
+
self::NOTICE => 'NOTICE',
|
88 |
+
self::WARNING => 'WARNING',
|
89 |
+
self::ERROR => 'ERROR',
|
90 |
+
self::CRITICAL => 'CRITICAL',
|
91 |
+
self::ALERT => 'ALERT',
|
92 |
+
self::EMERGENCY => 'EMERGENCY',
|
93 |
+
);
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @since 4.8.1
|
97 |
+
*/
|
98 |
+
protected function _construct()
|
99 |
+
{
|
100 |
+
if (!$this->hasName()) {
|
101 |
+
$this->setName('default');
|
102 |
+
}
|
103 |
+
|
104 |
+
parent::_construct();
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Add a log entry.
|
109 |
+
*
|
110 |
+
* @since 4.8.1
|
111 |
+
* @param int $level The level of the log entry. See {@link LoggerAbstract::getLevels()}.
|
112 |
+
* @param string $message The message of the entry. Something that can be converted to string.
|
113 |
+
* @param array $context The context of the entry. Additional data about the environment.
|
114 |
+
* @return LoggerAbstract This instance.
|
115 |
+
*/
|
116 |
+
public function addRecord($level, $message, array $context = array())
|
117 |
+
{
|
118 |
+
$this->_addRecord($level, $message, $context);
|
119 |
+
return $this;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Add a log entry.
|
124 |
+
*
|
125 |
+
* @since 4.8.1
|
126 |
+
* @param int $level The level of the log entry. See {@link LoggerAbstract::getLevels()}.
|
127 |
+
* @param string $message The message of the entry. Something that can be converted to string.
|
128 |
+
* @param array $context The context of the entry. Additional data about the environment.
|
129 |
+
* @return LoggerAbstract This instance.
|
130 |
+
*/
|
131 |
+
protected function _addRecord($level, $message, array $context = array())
|
132 |
+
{
|
133 |
+
if (!$this->shouldAddRecord($level, $message, $context)) {
|
134 |
+
return false;
|
135 |
+
}
|
136 |
+
|
137 |
+
$levelName = static::getLevelName($level);
|
138 |
+
$date = date('Y-m-d H:i:s');
|
139 |
+
// $format = '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'; // Default format
|
140 |
+
$format = '[%1$s] %2$s.%3$s (%5$s): '."\n".'%4$s'."\n";
|
141 |
+
$str = sprintf($format, $date, // Date
|
142 |
+
$this->getName(), // Channel
|
143 |
+
$levelName, // Level Name
|
144 |
+
$message, // Message
|
145 |
+
isset($context['source']) ? $context['source'] : '' // Context
|
146 |
+
);
|
147 |
+
|
148 |
+
if (!($path = $this->getLogFilePath())) {
|
149 |
+
throw $this->exception('Could not add log record: Log path must be set');
|
150 |
+
}
|
151 |
+
file_put_contents($path, $str, FILE_APPEND);
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Gets the name of the logging level.
|
156 |
+
*
|
157 |
+
* @since 4.8.1
|
158 |
+
* @param int $level
|
159 |
+
* @return string
|
160 |
+
*/
|
161 |
+
public static function getLevelName($level)
|
162 |
+
{
|
163 |
+
if (!isset(static::$_levels[$level])) {
|
164 |
+
throw new \InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ',
|
165 |
+
array_keys(static::$levels)));
|
166 |
+
}
|
167 |
+
return static::$_levels[$level];
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Get the value of the log level.
|
172 |
+
*
|
173 |
+
* @since 4.8.1
|
174 |
+
* @param string $logLevel The string representation of the log level, case-insensitive.
|
175 |
+
* @return int The numeric representation of the log level.
|
176 |
+
*/
|
177 |
+
public static function getLogLevelValue($logLevel)
|
178 |
+
{
|
179 |
+
$constName = static::WPRSS_LOG_LEVEL_PREFIX.strtoupper($logLevel);
|
180 |
+
return defined($constName) ? constant($constName) : null;
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* All levels available.
|
185 |
+
*
|
186 |
+
* @since 4.8.1
|
187 |
+
* @return array An array of all levels of this logger, where keys are numeric
|
188 |
+
* level values, and values are their string representations.
|
189 |
+
*/
|
190 |
+
public static function getLevels()
|
191 |
+
{
|
192 |
+
return array_flip(static::$_levels);
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Converts PSR-3 levels to Monolog ones if necessary
|
197 |
+
*
|
198 |
+
* @since 4.8.1
|
199 |
+
* @param string|int Level number (monolog) or name (PSR-3)
|
200 |
+
* @return int
|
201 |
+
*/
|
202 |
+
public static function toMonologLevel($level)
|
203 |
+
{
|
204 |
+
if (is_string($level)) {
|
205 |
+
|
206 |
+
if (defined(get_called_class().'::'.strtoupper($level))) {
|
207 |
+
return constant(get_called_class().'::'.strtoupper($level));
|
208 |
+
}
|
209 |
+
throw new \InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ',
|
210 |
+
array_keys(static::$levels)));
|
211 |
+
}
|
212 |
+
return $level;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Adds a log record at an arbitrary level.
|
217 |
+
*
|
218 |
+
* This method allows for compatibility with common interfaces.
|
219 |
+
*
|
220 |
+
* @since 4.8.1
|
221 |
+
* @param mixed $level The log level
|
222 |
+
* @param string $message The log message
|
223 |
+
* @param array $context The log context
|
224 |
+
* @return bool Whether the record has been processed
|
225 |
+
*/
|
226 |
+
public function log($level, $message, array $context = array())
|
227 |
+
{
|
228 |
+
$level = static::toMonologLevel($level);
|
229 |
+
return $this->addRecord($level, (string) $message, $context);
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Adds a log record at the DEBUG level.
|
234 |
+
*
|
235 |
+
* This method allows for compatibility with common interfaces.
|
236 |
+
*
|
237 |
+
* @since 4.8.1
|
238 |
+
* @param string $message The log message
|
239 |
+
* @param array $context The log context
|
240 |
+
* @return bool Whether the record has been processed
|
241 |
+
*/
|
242 |
+
public function debug($message, array $context = array())
|
243 |
+
{
|
244 |
+
return $this->addRecord(static::DEBUG, (string) $message, $context);
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Adds a log record at the INFO level.
|
249 |
+
*
|
250 |
+
* This method allows for compatibility with common interfaces.
|
251 |
+
*
|
252 |
+
* @since 4.8.1
|
253 |
+
* @param string $message The log message
|
254 |
+
* @param array $context The log context
|
255 |
+
* @return bool Whether the record has been processed
|
256 |
+
*/
|
257 |
+
public function info($message, array $context = array())
|
258 |
+
{
|
259 |
+
return $this->addRecord(static::INFO, (string) $message, $context);
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Adds a log record at the NOTICE level.
|
264 |
+
*
|
265 |
+
* This method allows for compatibility with common interfaces.
|
266 |
+
*
|
267 |
+
* @since 4.8.1
|
268 |
+
* @param string $message The log message
|
269 |
+
* @param array $context The log context
|
270 |
+
* @return bool Whether the record has been processed
|
271 |
+
*/
|
272 |
+
public function notice($message, array $context = array())
|
273 |
+
{
|
274 |
+
return $this->addRecord(static::NOTICE, (string) $message, $context);
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Adds a log record at the WARNING level.
|
279 |
+
*
|
280 |
+
* This method allows for compatibility with common interfaces.
|
281 |
+
*
|
282 |
+
* @since 4.8.1
|
283 |
+
* @param string $message The log message
|
284 |
+
* @param array $context The log context
|
285 |
+
* @return bool Whether the record has been processed
|
286 |
+
*/
|
287 |
+
public function warning($message, array $context = array())
|
288 |
+
{
|
289 |
+
return $this->addRecord(static::WARNING, (string) $message, $context);
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Adds a log record at the ERROR level.
|
294 |
+
*
|
295 |
+
* This method allows for compatibility with common interfaces.
|
296 |
+
*
|
297 |
+
* @since 4.8.1
|
298 |
+
* @param string $message The log message
|
299 |
+
* @param array $context The log context
|
300 |
+
* @return bool Whether the record has been processed
|
301 |
+
*/
|
302 |
+
public function error($message, array $context = array())
|
303 |
+
{
|
304 |
+
return $this->addRecord(static::ERROR, (string) $message, $context);
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Adds a log record at the CRITICAL level.
|
309 |
+
*
|
310 |
+
* This method allows for compatibility with common interfaces.
|
311 |
+
*
|
312 |
+
* @since 4.8.1
|
313 |
+
* @param string $message The log message
|
314 |
+
* @param array $context The log context
|
315 |
+
* @return bool Whether the record has been processed
|
316 |
+
*/
|
317 |
+
public function critical($message, array $context = array())
|
318 |
+
{
|
319 |
+
return $this->addRecord(static::CRITICAL, (string) $message, $context);
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Adds a log record at the ALERT level.
|
324 |
+
*
|
325 |
+
* This method allows for compatibility with common interfaces.
|
326 |
+
*
|
327 |
+
* @since 4.8.1
|
328 |
+
* @param string $message The log message
|
329 |
+
* @param array $context The log context
|
330 |
+
* @return bool Whether the record has been processed
|
331 |
+
*/
|
332 |
+
public function alert($message, array $context = array())
|
333 |
+
{
|
334 |
+
return $this->addRecord(static::ALERT, (string) $message, $context);
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Adds a log record at the EMERGENCY level.
|
339 |
+
*
|
340 |
+
* This method allows for compatibility with common interfaces.
|
341 |
+
*
|
342 |
+
* @since 4.8.1
|
343 |
+
* @param string $message The log message
|
344 |
+
* @param array $context The log context
|
345 |
+
* @return bool Whether the record has been processed
|
346 |
+
*/
|
347 |
+
public function emergency($message, array $context = array())
|
348 |
+
{
|
349 |
+
return $this->addRecord(static::EMERGENCY, (string) $message, $context);
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Whether or not to add the record described by specified arguments.
|
354 |
+
*
|
355 |
+
* @since 4.8.1
|
356 |
+
* @param mixed $level The log level
|
357 |
+
* @param string $message The log message
|
358 |
+
* @param array $context The log context
|
359 |
+
*/
|
360 |
+
public function shouldAddRecord($level, $message, array $context = array())
|
361 |
+
{
|
362 |
+
return true;
|
363 |
+
}
|
364 |
+
}
|
includes/Aventura/Wprss/Core/Model/LoggerInterface.php
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* This is actually taken from here:
|
7 |
+
* https://github.com/php-fig/log/blob/master/Psr/Log/LoggerInterface.php
|
8 |
+
*
|
9 |
+
* This is done for forward-compatibility with monolog/monolog, or any other PSR-compatible logger.
|
10 |
+
*
|
11 |
+
* @todo When possible, declare Psr\Log as a dependency. Consider using monolog/monolog.
|
12 |
+
* @since 4.8.1
|
13 |
+
*/
|
14 |
+
interface LoggerInterface
|
15 |
+
{
|
16 |
+
|
17 |
+
/**
|
18 |
+
* System is unusable.
|
19 |
+
*
|
20 |
+
* @param string $message
|
21 |
+
* @param array $context
|
22 |
+
*
|
23 |
+
* @return null
|
24 |
+
*/
|
25 |
+
public function emergency($message, array $context = array());
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Action must be taken immediately.
|
29 |
+
*
|
30 |
+
* Example: Entire website down, database unavailable, etc. This should
|
31 |
+
* trigger the SMS alerts and wake you up.
|
32 |
+
*
|
33 |
+
* @param string $message
|
34 |
+
* @param array $context
|
35 |
+
*
|
36 |
+
* @return null
|
37 |
+
*/
|
38 |
+
public function alert($message, array $context = array());
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Critical conditions.
|
42 |
+
*
|
43 |
+
* Example: Application component unavailable, unexpected exception.
|
44 |
+
*
|
45 |
+
* @param string $message
|
46 |
+
* @param array $context
|
47 |
+
*
|
48 |
+
* @return null
|
49 |
+
*/
|
50 |
+
public function critical($message, array $context = array());
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Runtime errors that do not require immediate action but should typically
|
54 |
+
* be logged and monitored.
|
55 |
+
*
|
56 |
+
* @param string $message
|
57 |
+
* @param array $context
|
58 |
+
*
|
59 |
+
* @return null
|
60 |
+
*/
|
61 |
+
public function error($message, array $context = array());
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Exceptional occurrences that are not errors.
|
65 |
+
*
|
66 |
+
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
67 |
+
* that are not necessarily wrong.
|
68 |
+
*
|
69 |
+
* @param string $message
|
70 |
+
* @param array $context
|
71 |
+
*
|
72 |
+
* @return null
|
73 |
+
*/
|
74 |
+
public function warning($message, array $context = array());
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Normal but significant events.
|
78 |
+
*
|
79 |
+
* @param string $message
|
80 |
+
* @param array $context
|
81 |
+
*
|
82 |
+
* @return null
|
83 |
+
*/
|
84 |
+
public function notice($message, array $context = array());
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Interesting events.
|
88 |
+
*
|
89 |
+
* Example: User logs in, SQL logs.
|
90 |
+
*
|
91 |
+
* @param string $message
|
92 |
+
* @param array $context
|
93 |
+
*
|
94 |
+
* @return null
|
95 |
+
*/
|
96 |
+
public function info($message, array $context = array());
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Detailed debug information.
|
100 |
+
*
|
101 |
+
* @param string $message
|
102 |
+
* @param array $context
|
103 |
+
*
|
104 |
+
* @return null
|
105 |
+
*/
|
106 |
+
public function debug($message, array $context = array());
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Logs with an arbitrary level.
|
110 |
+
*
|
111 |
+
* @param mixed $level
|
112 |
+
* @param string $message
|
113 |
+
* @param array $context
|
114 |
+
*
|
115 |
+
* @return null
|
116 |
+
*/
|
117 |
+
public function log($level, $message, array $context = array());
|
118 |
+
}
|
includes/Aventura/Wprss/Core/Model/ModelAbstract.php
ADDED
@@ -0,0 +1,362 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
abstract class ModelAbstract extends Core\DataObject implements ModelInterface
|
11 |
+
{
|
12 |
+
const PREFIX_OVERRIDE = '!';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @since 4.8.1
|
16 |
+
*/
|
17 |
+
protected function _construct()
|
18 |
+
{
|
19 |
+
// Default depth
|
20 |
+
if (!$this->hasBaseNamespaceDepth()) {
|
21 |
+
$this->setBaseNamespaceDepth(3);
|
22 |
+
}
|
23 |
+
parent::_construct();
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Translates a string of text.
|
28 |
+
*
|
29 |
+
* If text is an array, it will be used as an array to a format function,
|
30 |
+
* such as {@see sprintf()}.
|
31 |
+
* Formatting always takes place after translation; only the first element
|
32 |
+
* of the text array will be translated.
|
33 |
+
* If the text is a scalar value other than string, it will be returned unmodified.
|
34 |
+
*
|
35 |
+
* @since 4.8.1
|
36 |
+
* @param string|array $text The text to translate, or an array of arguments to a format function.
|
37 |
+
* @param string|mixed $translator A translator instance or some kind of identifier.
|
38 |
+
* @return string Translated string.
|
39 |
+
* @throws \InvalidArgumentException If trying to translate an untranslatable value.
|
40 |
+
*/
|
41 |
+
public function __($text, $translator = null)
|
42 |
+
{
|
43 |
+
// Allowing array to designate message formatting
|
44 |
+
$args = (array)$text;
|
45 |
+
$text = array_shift($args);
|
46 |
+
$isString = is_string($text);
|
47 |
+
$isScalar = is_scalar($text);
|
48 |
+
$canStringify = $isString || $isScalar;
|
49 |
+
|
50 |
+
if (!$canStringify) {
|
51 |
+
throw new \InvalidArgumentException('Could not process text: Text must be a string, or at least of a scalar type');
|
52 |
+
}
|
53 |
+
|
54 |
+
$text = (string)$text;
|
55 |
+
if (!$isString) {
|
56 |
+
return $text;
|
57 |
+
}
|
58 |
+
|
59 |
+
// Allowing to skip message translation
|
60 |
+
if ($translator !== false) {
|
61 |
+
$text = $this->_translate($text, $translator);
|
62 |
+
}
|
63 |
+
|
64 |
+
array_unshift($args, $text);
|
65 |
+
|
66 |
+
if (count($args) > 1) {
|
67 |
+
// Formatting message
|
68 |
+
$result = call_user_func_array('sprintf', $args);
|
69 |
+
|
70 |
+
// Detecting format error
|
71 |
+
if (!strlen($result) && strlen($text)) {
|
72 |
+
error_log($text);
|
73 |
+
throw new \InvalidArgumentException(sprintf('Could not process text: It seems there was an error with formatting, '
|
74 |
+
.'perhaps wrong parameter count (string should contain %1$d).', count($args) - 1));
|
75 |
+
}
|
76 |
+
}
|
77 |
+
else {
|
78 |
+
$result = $args[0];
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
return $result;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Translates a string.
|
87 |
+
*
|
88 |
+
* @since 4.8.1
|
89 |
+
* @param string $text The text to translate.
|
90 |
+
* @param string|mixed $translator A translator instance or some kind of identifier.
|
91 |
+
* @return string Translated string.
|
92 |
+
*/
|
93 |
+
protected function _translate($text, $translator = null) {
|
94 |
+
return $text;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Get the namespace of this or other class
|
99 |
+
*
|
100 |
+
* @since 4.8.1
|
101 |
+
* @see wprss_get_namespace()
|
102 |
+
* @param int|null $depth The depth of the namespace to retrieve.
|
103 |
+
* If omitted, the whole namespace will be retrieved.
|
104 |
+
* @param string|object|null $class The class name or instance, for which to get the namespace.
|
105 |
+
* If omitted, the current class will be used.
|
106 |
+
* @param bool $asString If true, the result will be a string; otherwise, array with namespace parts.
|
107 |
+
* @return array|string The namespace of the class.
|
108 |
+
*/
|
109 |
+
public static function getNamespace($depth = null, $class = null,
|
110 |
+
$asString = false)
|
111 |
+
{
|
112 |
+
// Default to this class
|
113 |
+
if (is_null($class)) {
|
114 |
+
$className = trim(get_called_class(), $ns);
|
115 |
+
}
|
116 |
+
return wprss_get_namespace($class, $depth, $asString);
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Check if a namespace is a root namespace.
|
121 |
+
*
|
122 |
+
* @since 4.8.1
|
123 |
+
* @see wprss_is_root_namespace()
|
124 |
+
* @param string $namespace The namespace to check.
|
125 |
+
* @param bool $isCheckClass If true, and a class or interface with the name of the specified namespace exists,
|
126 |
+
* will make this function return true. Otherwise, the result depends purely on the namespace string.
|
127 |
+
* @return boolean True if the namespace is a root namespace; false otherwise.
|
128 |
+
*/
|
129 |
+
public static function isRootNamespace($namespace, $isCheckClass = true)
|
130 |
+
{
|
131 |
+
return wprss_is_root_namespace($namespace, $isCheckClass);
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Get the base namespace of this plugin.
|
136 |
+
*
|
137 |
+
* At least most of the classes in a plugin will be relative to that plugin's namespace.
|
138 |
+
* The default namespace is the namespace of this class, of an optional depth which is determined by
|
139 |
+
* {@see getBaseNamespaceDepth()}.
|
140 |
+
*
|
141 |
+
* @since 4.8.1
|
142 |
+
* @return string The base namespace of this plugin.
|
143 |
+
*/
|
144 |
+
public function getBaseNamespace()
|
145 |
+
{
|
146 |
+
if ($namespace = $this->getData('base_namespace')) {
|
147 |
+
return $namespace;
|
148 |
+
}
|
149 |
+
|
150 |
+
// Fall back to auto namespace
|
151 |
+
return static::getNamespace($this->getBaseNamespaceDepth(), $this, true);
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Creates an exception instance.
|
156 |
+
*
|
157 |
+
* @since 4.8.1
|
158 |
+
* @param string|array $text The text to translate.
|
159 |
+
* If array, then the result will be formatted with `sprintf()`, using
|
160 |
+
* the first argument as the format string, and any that follow as arguments.
|
161 |
+
* @param string $className The name of the exception's class.
|
162 |
+
* If it doesn't start with a backslash '\', will be treated as relative to
|
163 |
+
* the plugin base namespace.
|
164 |
+
* Defaults to 'Exception', which results in class [base_namespace]\Exception.
|
165 |
+
* {@see getExceptionClassName()}
|
166 |
+
* @param string|bool|null $translate The text domain to use for translation.
|
167 |
+
* If false, no translation will be made.
|
168 |
+
* Defaults to the current plugin's text domain.
|
169 |
+
* {@see __()}
|
170 |
+
* @return \Exception The new exception instance.
|
171 |
+
* @throws Aventura\Wprss\SpinnerChief\Plugin\Exception If the exception class does not exist.
|
172 |
+
*/
|
173 |
+
public function exception($text, $className = null, $translate = null)
|
174 |
+
{
|
175 |
+
$text = $this->__($text, $translate);
|
176 |
+
$className = $this->getExceptionClassName($className);
|
177 |
+
if (!class_exists($className)) {
|
178 |
+
throw new Exception(sprintf('Could not create exception: Class "%1$s" does not exist'));
|
179 |
+
}
|
180 |
+
|
181 |
+
$exception = new $className($text);
|
182 |
+
return $exception;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Get a class name of an exception.
|
187 |
+
*
|
188 |
+
* This will be based on its absolute or relative class name, or potentially
|
189 |
+
* any other identifier that could be mapped to a class name.
|
190 |
+
*
|
191 |
+
* @since 4.8.1
|
192 |
+
* @see getExceptionClassRoot()
|
193 |
+
* @param string|array $className A name of the exception class, or array with namespace parts.
|
194 |
+
* If array, assumed to be root namespace.
|
195 |
+
* @return string The fully qualified name of the exception class.
|
196 |
+
*/
|
197 |
+
public function getExceptionClassName($className = null)
|
198 |
+
{
|
199 |
+
$defaultClassName = 'Exception';
|
200 |
+
// Defaults to this namespace's root exception
|
201 |
+
if (is_null($className)) {
|
202 |
+
$className = $defaultClassName;
|
203 |
+
}
|
204 |
+
|
205 |
+
// Namespace specified as array of parts; assume root namespace
|
206 |
+
if (is_array($className)) {
|
207 |
+
$className = '\\' . trim(implode('\\', $className), '\\');
|
208 |
+
}
|
209 |
+
|
210 |
+
// Allowing explicit class name
|
211 |
+
if (static::isRootNamespace($className, $className !== $defaultClassName)) {
|
212 |
+
return $className;
|
213 |
+
}
|
214 |
+
|
215 |
+
// Relative to this class's root
|
216 |
+
$rootNamespace = $this->getExceptionClassRoot();
|
217 |
+
return sprintf('%1$s\\%2$s', $rootNamespace, $className);
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Get the root namespace for exception classes.
|
222 |
+
*
|
223 |
+
* Unless altered, {@see getExceptionClassName} will process class names
|
224 |
+
* relative to the value returned by this method.
|
225 |
+
*
|
226 |
+
* @since 4.8.1
|
227 |
+
* @return string The root namespace of exception class names.
|
228 |
+
*/
|
229 |
+
public function getExceptionClassRoot()
|
230 |
+
{
|
231 |
+
$key = 'exception_class_root';
|
232 |
+
if (!$this->hasData($key)) {
|
233 |
+
$this->setData($key, $this->getBaseNamespace());
|
234 |
+
}
|
235 |
+
|
236 |
+
return $this->getData($key);
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
*
|
241 |
+
* @since 4.8.1
|
242 |
+
* @param string $string The string to check.
|
243 |
+
* @return bool True if the string had a prefix override, and it was removed;
|
244 |
+
* false otherwise;
|
245 |
+
*/
|
246 |
+
public static function stringHadPrefix(&$string)
|
247 |
+
{
|
248 |
+
return string_had_prefix($string, static::PREFIX_OVERRIDE);
|
249 |
+
}
|
250 |
+
|
251 |
+
public static function classImplements($class, $interface = null, $autoload = true)
|
252 |
+
{
|
253 |
+
$interfaces = class_implements($class, $autoload);
|
254 |
+
if (is_null($interface)) {
|
255 |
+
return $interfaces;
|
256 |
+
}
|
257 |
+
|
258 |
+
return in_array($interface, $interfaces);
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Gets the data member with the specified key, or a corresponding constant if that key is not defined.
|
263 |
+
*
|
264 |
+
* Useful for accessing data, the default value of which was defined as a class constants.
|
265 |
+
*
|
266 |
+
* @since 4.8.1
|
267 |
+
* @param string $key The data key to get.
|
268 |
+
* @param mixed|null $default What to return if neither the data key or the constant are defined.
|
269 |
+
* @return mixed|null The value of the data key or constant.
|
270 |
+
*/
|
271 |
+
protected function _getDataOrConst($key, $default = null)
|
272 |
+
{
|
273 |
+
if ($this->hasData($key)) {
|
274 |
+
return $this->getData();
|
275 |
+
}
|
276 |
+
|
277 |
+
$const = $this->constant($key);
|
278 |
+
return empty($const)
|
279 |
+
? $default
|
280 |
+
: $const;
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Gets the value of a constant with the specified name from this object's class.
|
285 |
+
*
|
286 |
+
* @since 4.8.1
|
287 |
+
* @param string $key The key of the constant, which corresponds to it's name.
|
288 |
+
* @param mixed|null $default What to return if the constant with the specified key is not defined.
|
289 |
+
* @param bool $toUpper Whether or not to convert the key to uppercase.
|
290 |
+
* @return int|string|null The value of the constant, or `null` if no such constant defined.
|
291 |
+
*/
|
292 |
+
public function constant($key, $default = null, $toUpper = true)
|
293 |
+
{
|
294 |
+
if ($toUpper) {
|
295 |
+
$key = strtoupper($key);
|
296 |
+
}
|
297 |
+
|
298 |
+
$constName = sprintf('%1$s::%2$s', get_class($this), $key);
|
299 |
+
return defined($constName)
|
300 |
+
? constant($constName)
|
301 |
+
: $default;
|
302 |
+
}
|
303 |
+
|
304 |
+
public function log($level, $message, array $context = array())
|
305 |
+
{
|
306 |
+
return false;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Get this instance's event prefix, or a prefixed event name.
|
311 |
+
*
|
312 |
+
* An event prefix is a prefix that will by default be added to names of events
|
313 |
+
* that are listened to or raised by this instance.
|
314 |
+
*
|
315 |
+
* The event prefix is by default the plugin code followed by an underscore "_", unless the code is
|
316 |
+
* not set, in which case the prefix is empty.
|
317 |
+
*
|
318 |
+
* Override with setEventPrefix().
|
319 |
+
*
|
320 |
+
* @since 4.8.1
|
321 |
+
* @param string|null $name An event name to prefix.
|
322 |
+
* @return string This instance's event prefix, or a prefixed name.
|
323 |
+
*/
|
324 |
+
public function getEventPrefix($name = null)
|
325 |
+
{
|
326 |
+
$prefix = $this->_getEventPrefix();
|
327 |
+
return static::stringHadPrefix($name)
|
328 |
+
? $name
|
329 |
+
: "{$prefix}{$name}";
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Get the actual event prefix, only.
|
334 |
+
*
|
335 |
+
* @since 4.8.1
|
336 |
+
* @return string
|
337 |
+
*/
|
338 |
+
protected function _getEventPrefix()
|
339 |
+
{
|
340 |
+
return $this->getData('event_prefix');
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* {@inheritdoc}
|
345 |
+
*
|
346 |
+
* @since 4.8.1
|
347 |
+
*/
|
348 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null)
|
349 |
+
{
|
350 |
+
return false;
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* {@inheritdoc}
|
355 |
+
*
|
356 |
+
* @since 4.8.1
|
357 |
+
*/
|
358 |
+
public function event($name, $data = array())
|
359 |
+
{
|
360 |
+
return null;
|
361 |
+
}
|
362 |
+
}
|
includes/Aventura/Wprss/Core/Model/ModelInterface.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Anything that can be a model.
|
7 |
+
*
|
8 |
+
* A model is something that solves a particular problem, e.g. represents a problem domain.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
interface ModelInterface
|
13 |
+
{
|
14 |
+
/**
|
15 |
+
*
|
16 |
+
* @param string $text The text to translate.
|
17 |
+
* @param mixed $translator Something that determines how to translate the text.
|
18 |
+
*/
|
19 |
+
public function __($text, $translator = null);
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Logs a message
|
23 |
+
*
|
24 |
+
* @since 4.8.1
|
25 |
+
* @see LoggerAbstract
|
26 |
+
* @return bool True if log entry was processed; false otherwise.
|
27 |
+
*/
|
28 |
+
public function log($level, $message, array $context = array());
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Add an event listener.
|
32 |
+
*
|
33 |
+
* @since 4.8.1
|
34 |
+
* @param string $name Event name.
|
35 |
+
* @param callable $listener The event listener.
|
36 |
+
* @param null|array $data Additional data to be passed to event handlers. May not work on native system events.
|
37 |
+
* If the event gets passed data with same names when raised, they will override data passed here.
|
38 |
+
* @param int|null $priority Order priority of the listener. If null, implementation-specific default will be assumed.
|
39 |
+
* @param int|null $acceptedArgs The number of arguments to be passed to the handler. If null,
|
40 |
+
* implementation-specific default will be assumed.
|
41 |
+
* @return string|bool The eventual name of the event that was used on success; false if listener not registered.
|
42 |
+
*/
|
43 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null);
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Raise an event.
|
47 |
+
*
|
48 |
+
* This triggers all event handlers.
|
49 |
+
*
|
50 |
+
* @since 4.8.1
|
51 |
+
* @param string $name Name of the event to raise
|
52 |
+
* @param array $data The data to pass to the event handlers. This will be passed as the first and only argument.
|
53 |
+
* If additional data members were passed with {@see ModelInterface::on()}, members passed here will override.
|
54 |
+
* @return Core\Model\Event\EventInterface
|
55 |
+
*/
|
56 |
+
public function event($name, $data = array());
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Get this instance's event prefix, or a prefixed event name.
|
60 |
+
*
|
61 |
+
* An event prefix is a prefix that will by default be added to names of events
|
62 |
+
* that are listened to or raised by this instance.
|
63 |
+
*
|
64 |
+
* The event prefix is by default the plugin code followed by an underscore "_", unless the code is
|
65 |
+
* not set, in which case the prefix is empty.
|
66 |
+
*
|
67 |
+
* @since 4.8.1
|
68 |
+
* @param string|null $name An event name to prefix.
|
69 |
+
* @return string This instance's event prefix, or a prefixed name.
|
70 |
+
*/
|
71 |
+
public function getEventPrefix($name = null);
|
72 |
+
}
|
includes/Aventura/Wprss/Core/Model/SettingsAbstract.php
ADDED
@@ -0,0 +1,862 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Common functionality for objects that handle settings.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
abstract class SettingsAbstract extends Core\Plugin\ComponentAbstract implements SettingsInterface
|
13 |
+
{
|
14 |
+
const MAIN_OPTION_NAME = '';
|
15 |
+
const TRUE_VALUE = '1';
|
16 |
+
const FALSE_VALUE = '0';
|
17 |
+
|
18 |
+
protected $_sectionsFields;
|
19 |
+
protected $_fieldRenderers;
|
20 |
+
protected $_defaultValues;
|
21 |
+
|
22 |
+
protected $_isValuesLoaded;
|
23 |
+
// Purely to avoid recursion during values loading
|
24 |
+
protected $_isValuesLoading;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Gets the name of the main option, where the settings are stored.
|
28 |
+
*
|
29 |
+
* The settings are stored as a serialized array.
|
30 |
+
* The name defaults to '_settings', prefixed with the plugin code.
|
31 |
+
*
|
32 |
+
* @since 4.8.1
|
33 |
+
* @return string The name of the main option in the database.
|
34 |
+
*/
|
35 |
+
public function getMainOptionName()
|
36 |
+
{
|
37 |
+
return $this->_getDataOrConst('main_option_name',
|
38 |
+
sprintf('%1$s_settings', $this->getPluginCode()));
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Get the slug of the settings subpage or tab.
|
43 |
+
*
|
44 |
+
* @since 4.8.1
|
45 |
+
* @return string The slug
|
46 |
+
*/
|
47 |
+
public function getTabSlug()
|
48 |
+
{
|
49 |
+
return $this->_getDataOrConst('tab_slug', $this->getMainOptionName());
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Get the values from the database.
|
54 |
+
*
|
55 |
+
* No cache used here.
|
56 |
+
*
|
57 |
+
* @since 4.8.1
|
58 |
+
* @return array The array of settings as retrieved from the database.
|
59 |
+
*/
|
60 |
+
public function getValuesDb()
|
61 |
+
{
|
62 |
+
$default = array();
|
63 |
+
$option = static::getOption($this->getMainOptionName(), $default);
|
64 |
+
if (is_string($option)) {
|
65 |
+
$option = $default;
|
66 |
+
}
|
67 |
+
|
68 |
+
return $option;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Gets the default values for settings.
|
73 |
+
*
|
74 |
+
* The load will only be performed once, fildered with a prefixed `settings_defaults` hook,
|
75 |
+
* and then cached.
|
76 |
+
*
|
77 |
+
* @since 4.8.1
|
78 |
+
* @return array An array of default values, where keys correspond to the setting IDs.
|
79 |
+
*/
|
80 |
+
public function getDefaultValues()
|
81 |
+
{
|
82 |
+
if (is_null($this->_defaultValues)) {
|
83 |
+
$this->_defaultValues = $this->event('settings_defaults', array('values' => $this->_getDefaultValues()))
|
84 |
+
->getValues();
|
85 |
+
}
|
86 |
+
|
87 |
+
return $this->_defaultValues;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Gets the default values for settings.
|
92 |
+
*
|
93 |
+
* @since 4.8.1
|
94 |
+
* @return array A raw array of default values. Keys should correspond to setting IDs.
|
95 |
+
*/
|
96 |
+
abstract protected function _getDefaultValues();
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Loads the values from the database.
|
100 |
+
*
|
101 |
+
* @since 4.8.1
|
102 |
+
* @return array The loaded values.
|
103 |
+
*/
|
104 |
+
protected function _loadValues()
|
105 |
+
{
|
106 |
+
$this->_isValuesLoading = true;
|
107 |
+
$dbValues = $this->getValuesDb();
|
108 |
+
$defaults = $this->getDefaultValues();
|
109 |
+
$options = array_merge_recursive_distinct($defaults, $dbValues);
|
110 |
+
foreach ($options as $key => $value) {
|
111 |
+
$this->setDataUsingMethod($key, $value);
|
112 |
+
}
|
113 |
+
|
114 |
+
$this->_isValuesLoaded = true;
|
115 |
+
$this->_isValuesLoading = false;
|
116 |
+
return $this;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Whether or not the setting values have been loaded.
|
121 |
+
*
|
122 |
+
* @since 4.8.1
|
123 |
+
* @return bool True if values have been loaded; false otherwise.
|
124 |
+
*/
|
125 |
+
public function isValuesLoaded()
|
126 |
+
{
|
127 |
+
return (bool)$this->_isValuesLoaded;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Whether or not values are currently loading.
|
132 |
+
*
|
133 |
+
* This is needed to avoid recursion while loading values.
|
134 |
+
*
|
135 |
+
* @since 4.8.1
|
136 |
+
* @return bool True if the values are currently loading; false otherwise.
|
137 |
+
*/
|
138 |
+
protected function _isValuesLoading()
|
139 |
+
{
|
140 |
+
return (bool)$this->_isValuesLoading;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* {@inheritdoc}
|
145 |
+
*
|
146 |
+
* @since 4.8.1
|
147 |
+
* @param type $key
|
148 |
+
* @param type $index
|
149 |
+
* @return type
|
150 |
+
*/
|
151 |
+
public function getData($key = '', $index = null)
|
152 |
+
{
|
153 |
+
if (!$this->isValuesLoaded() && !$this->_isValuesLoading()) {
|
154 |
+
$this->_loadValues();
|
155 |
+
}
|
156 |
+
|
157 |
+
return parent::getData($key, $index);
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Gets the data for a settings tab.
|
162 |
+
*
|
163 |
+
* @since 4.8.1
|
164 |
+
* @return array Data for the settings tab.
|
165 |
+
*/
|
166 |
+
public function getTabData()
|
167 |
+
{
|
168 |
+
return array(
|
169 |
+
'label' => $this->getPlugin()->getName(),
|
170 |
+
'slug' => $this->getTabSlug()
|
171 |
+
);
|
172 |
+
}
|
173 |
+
|
174 |
+
|
175 |
+
/**
|
176 |
+
* A hook handler, typically intended for `wprss_options_tabs`.
|
177 |
+
*
|
178 |
+
* Adds the data about this settings page's tab to the list of tabs.
|
179 |
+
*
|
180 |
+
* @since 4.8.1
|
181 |
+
* @param array $tabs An array of registered tabs.
|
182 |
+
* @return array The array of registered tabs, now also containing an entry for this addon's tab.
|
183 |
+
*/
|
184 |
+
public function addTab($tabs)
|
185 |
+
{
|
186 |
+
$tabs[$this->getPluginCode()] = $this->getTabData();
|
187 |
+
return $tabs;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Does the registration of the main setting.
|
192 |
+
*
|
193 |
+
* @since 4.8.1
|
194 |
+
* @return SettingsAbstract
|
195 |
+
*/
|
196 |
+
protected function _registerSetting()
|
197 |
+
{
|
198 |
+
$optionName = $this->getMainOptionName();
|
199 |
+
register_setting(
|
200 |
+
$optionName, // Settings group name
|
201 |
+
$optionName, // Name of setting to save in db and sanitize
|
202 |
+
array($this, 'validate') // Validation callback
|
203 |
+
);
|
204 |
+
|
205 |
+
return $this;
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Registeres a section and its settings.
|
210 |
+
*
|
211 |
+
* @since 4.8.1
|
212 |
+
* @param array|Core\DataObjectInterface $section Section data.
|
213 |
+
* Should contain information about the section, as well as the array of fields in the 'fields' index.
|
214 |
+
*/
|
215 |
+
protected function _registerSection($section)
|
216 |
+
{
|
217 |
+
$fields = null;
|
218 |
+
if ($section instanceof Core\DataObjectInterface) {
|
219 |
+
$fields = $section->getFields();
|
220 |
+
$section = $section->getData();
|
221 |
+
}
|
222 |
+
|
223 |
+
add_settings_section(
|
224 |
+
$this->getSectionId($section['id']),
|
225 |
+
$section['label'],
|
226 |
+
$this->createCommand(array($this, '_renderSectionHeader'), array($section)),
|
227 |
+
$this->getMainOptionName()
|
228 |
+
);
|
229 |
+
|
230 |
+
if (is_null($fields) && isset($section['fields'])) {
|
231 |
+
$fields = $section['fields'];
|
232 |
+
}
|
233 |
+
|
234 |
+
if (!is_array($fields)) {
|
235 |
+
$fields = array();
|
236 |
+
}
|
237 |
+
|
238 |
+
foreach ($fields as $_fieldId => $_field) {
|
239 |
+
if (!is_array($_field)) {
|
240 |
+
$_field = array('label' => $_field);
|
241 |
+
}
|
242 |
+
$_field['id'] = $_fieldId;
|
243 |
+
$_field['section_id'] = $section['id'];
|
244 |
+
$this->_registerField($_field);
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Registers a single field.
|
250 |
+
*
|
251 |
+
* @since 4.8.1
|
252 |
+
* @param array|Core\DataObjectInterface $field Data of a field.
|
253 |
+
*/
|
254 |
+
protected function _registerField($field)
|
255 |
+
{
|
256 |
+
if ($field instanceof Core\DataObjectInterface) {
|
257 |
+
$field = $field->getData();
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* @var This will be passed to the field callback as the only argument
|
262 |
+
* @see http://codex.wordpress.org/Function_Reference/add_settings_field#Parameters
|
263 |
+
*/
|
264 |
+
$callbackArgs = $field;
|
265 |
+
if (!isset($callbackArgs['label'])) {
|
266 |
+
$callbackArgs['label'] = null;
|
267 |
+
}
|
268 |
+
if (!isset($callbackArgs['tooltip'])) {
|
269 |
+
$callbackArgs['tooltip'] = null;
|
270 |
+
}
|
271 |
+
if (!isset($callbackArgs['value'])) {
|
272 |
+
$callbackArgs['value'] = $this->createLocalDataSource($field['id']);
|
273 |
+
}
|
274 |
+
|
275 |
+
add_settings_field(
|
276 |
+
$this->getIdPrefix($field['id']),
|
277 |
+
$field['label'],
|
278 |
+
array($this, 'renderField'),
|
279 |
+
$this->getMainOptionName(),
|
280 |
+
$this->getSectionId($field['section_id']),
|
281 |
+
$callbackArgs
|
282 |
+
);
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Registers the settings page for these settings.
|
287 |
+
*
|
288 |
+
* @since 4.8.1
|
289 |
+
*/
|
290 |
+
abstract protected function _registerSettingsPage();
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Renders a header of a section.
|
294 |
+
*
|
295 |
+
* This is intended to be a callback for {@see add_settings_section()}.
|
296 |
+
*
|
297 |
+
* @since 4.8.1
|
298 |
+
* @param array $data Has 3 elmenets: 'id', 'title', 'callback'.
|
299 |
+
*/
|
300 |
+
public function _renderSectionHeader($data)
|
301 |
+
{
|
302 |
+
echo isset($data['header'])
|
303 |
+
? $this->resolveDataSource($data['header'])
|
304 |
+
: '';
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Renders and outputs a field.
|
309 |
+
*
|
310 |
+
* @since 4.8.1
|
311 |
+
* @param array|Core\DataObjectInterface $field Data of a field.
|
312 |
+
*/
|
313 |
+
public function renderField($field)
|
314 |
+
{
|
315 |
+
echo $this->getFieldHtml($field);
|
316 |
+
}
|
317 |
+
|
318 |
+
/**
|
319 |
+
* Renders and gets HTML of a field.
|
320 |
+
*
|
321 |
+
* The output will depend on the data of the field, and also on its 'type'.
|
322 |
+
*
|
323 |
+
* @since 4.8.1
|
324 |
+
* @see getFieldRenderers()
|
325 |
+
* @param array|Core\DataObjectInterface $field Data of a field.
|
326 |
+
* @return string The output of the rendered field.
|
327 |
+
* @throws \Aventura\Wprss\SpinnerChief\Exception If no renderer is defined for the field type.
|
328 |
+
*/
|
329 |
+
public function getFieldHtml($field)
|
330 |
+
{
|
331 |
+
if ($field instanceof Core\DataObjectInterface) {
|
332 |
+
$field = $field->getData();
|
333 |
+
}
|
334 |
+
|
335 |
+
// Defaults
|
336 |
+
if (!isset($field['type'])) {
|
337 |
+
$field['type'] = 'text';
|
338 |
+
}
|
339 |
+
// Get actual data
|
340 |
+
if (isset($field['data'])) {
|
341 |
+
$field['data'] = $this->resolveDataSource($field['data']);
|
342 |
+
}
|
343 |
+
if (isset($field['value'])) {
|
344 |
+
$field['value'] = $this->resolveDataSource($field['value']);
|
345 |
+
}
|
346 |
+
|
347 |
+
// Choose rendering algo
|
348 |
+
if (!($renderer = $this->getFieldRenderers($field['type']))) {
|
349 |
+
throw $this->exception(array('Could not render field "%1$s": A renderer for field type "%1$s" must be defined', $field['id'], $field['type']));
|
350 |
+
}
|
351 |
+
|
352 |
+
return $this->resolveDataSource($renderer, array($field));
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Gets one or all field type renderers.
|
357 |
+
*
|
358 |
+
* Essentially, a renderer is a callback that receives information about a field,
|
359 |
+
* and returns the output of that field rendered.
|
360 |
+
*
|
361 |
+
* The renderers will be loaded once, then filtered with a prefixed `settings_field_renderers` hook,
|
362 |
+
* and cached.
|
363 |
+
*
|
364 |
+
* @since 4.8.1
|
365 |
+
* @param string $type A type, for which to get the renderer.
|
366 |
+
* @return array|callable All field renderers available, or one renderer.
|
367 |
+
*/
|
368 |
+
public function getFieldRenderers($type = null)
|
369 |
+
{
|
370 |
+
if (is_null($this->_fieldRenderers)) {
|
371 |
+
$this->_fieldRenderers = $this->event('settings_field_renderers', array('renderers' => $this->_getFieldRenderers()))
|
372 |
+
->getRenderers();
|
373 |
+
}
|
374 |
+
|
375 |
+
if (is_null($type)) {
|
376 |
+
return $this->_fieldRenderers;
|
377 |
+
}
|
378 |
+
|
379 |
+
return isset($this->_fieldRenderers[$type])
|
380 |
+
? $this->_fieldRenderers[$type]
|
381 |
+
: null;
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* Gets all available field renderers.
|
386 |
+
*
|
387 |
+
* Override this method to add more renderers to an instance from within itself.
|
388 |
+
*
|
389 |
+
* @since 4.8.1
|
390 |
+
* @return array An array of callables, each of which is a field renderer.
|
391 |
+
*/
|
392 |
+
protected function _getFieldRenderers()
|
393 |
+
{
|
394 |
+
return array(
|
395 |
+
'text' => $this->createCommand(array($this, 'renderTextField')),
|
396 |
+
'checkbox' => $this->createCommand(array($this, 'renderCheckboxField')),
|
397 |
+
'select' => $this->createCommand(array($this, 'renderSelectField')),
|
398 |
+
'number' => $this->createCommand(array($this, 'renderNumberField')),
|
399 |
+
);
|
400 |
+
}
|
401 |
+
|
402 |
+
/**
|
403 |
+
* Renders a text field.
|
404 |
+
*
|
405 |
+
* Normally, the output would be an <input> element of type 'text'.
|
406 |
+
*
|
407 |
+
* @since 4.8.1
|
408 |
+
* @param array|Core\DataObjectInterface $field Data of a field.
|
409 |
+
* @return string The text field HTML.
|
410 |
+
*/
|
411 |
+
public function renderTextField($field)
|
412 |
+
{
|
413 |
+
if ($field instanceof Core\DataObjectInterface) {
|
414 |
+
$field = $field->getData();
|
415 |
+
}
|
416 |
+
|
417 |
+
$id = $field['id'];
|
418 |
+
$htmlAttributes = array(
|
419 |
+
'id' => $this->getIdPrefix($id),
|
420 |
+
'name' => static::getNameHtml(array($this->getMainOptionName(), $id)),
|
421 |
+
);
|
422 |
+
$field = array_merge_recursive_distinct($field, $htmlAttributes);
|
423 |
+
return static::getTextHtml($field['value'], $field) .
|
424 |
+
$this->getPlugin()->getTooltips()->doTooltip($id);
|
425 |
+
}
|
426 |
+
|
427 |
+
/**
|
428 |
+
* Renders a number field.
|
429 |
+
*
|
430 |
+
* Normally, the output would be an <input> element of type 'number'.
|
431 |
+
*
|
432 |
+
* @since 4.8.1
|
433 |
+
* @param array|Core\DataObjectInterface $field Data of a field.
|
434 |
+
* @return string The number field HTML.
|
435 |
+
*/
|
436 |
+
public function renderNumberField($field)
|
437 |
+
{
|
438 |
+
if ($field instanceof Core\DataObjectInterface) {
|
439 |
+
$field = $field->getData();
|
440 |
+
}
|
441 |
+
|
442 |
+
$id = $field['id'];
|
443 |
+
$htmlAttributes = array(
|
444 |
+
'id' => $this->getIdPrefix($id),
|
445 |
+
'name' => static::getNameHtml(array($this->getMainOptionName(), $id)),
|
446 |
+
);
|
447 |
+
$field = array_merge_recursive_distinct($field, $htmlAttributes);
|
448 |
+
return static::getNumberHtml($field['value'], $field) .
|
449 |
+
$this->getPlugin()->getTooltips()->doTooltip($id);
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* Renders a checkbox field.
|
454 |
+
*
|
455 |
+
* Normally, the output would be an <input> element of type 'checkbox'.
|
456 |
+
*
|
457 |
+
* @since 4.8.1
|
458 |
+
* @param array|Core\DataObjectInterface $field Data of a field.
|
459 |
+
* @return string The checkbox field HTML.
|
460 |
+
*/
|
461 |
+
public function renderCheckboxField($field)
|
462 |
+
{
|
463 |
+
if ($field instanceof Core\DataObjectInterface) {
|
464 |
+
$field = $field->getData();
|
465 |
+
}
|
466 |
+
|
467 |
+
$id = $field['id'];
|
468 |
+
$trueValue = isset($field['true_value'])
|
469 |
+
? $field['true_value']
|
470 |
+
: static::getTrueValue();
|
471 |
+
$falseValue = isset($field['false_value'])
|
472 |
+
? $field['false_value']
|
473 |
+
: static::getFalseValue();
|
474 |
+
return static::getCheckboxHtml($field['value'], array(
|
475 |
+
'id' => $this->getIdPrefix($id),
|
476 |
+
'name' => static::getNameHtml(array($this->getMainOptionName(), $id)),
|
477 |
+
'value' => $trueValue,
|
478 |
+
'false_value' => $falseValue
|
479 |
+
)) .
|
480 |
+
$this->getPlugin()->getTooltips()->doTooltip($id);
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Renders a checkbox field.
|
485 |
+
*
|
486 |
+
* Normally, the output would be an <select> element.
|
487 |
+
*
|
488 |
+
* @since 4.8.1
|
489 |
+
* @param array|Core\DataObjectInterface $field Data of a field.
|
490 |
+
* @return string The select field HTML.
|
491 |
+
*/
|
492 |
+
public function renderSelectField($field)
|
493 |
+
{
|
494 |
+
if ($field instanceof Core\DataObjectInterface) {
|
495 |
+
$field = $field->getData();
|
496 |
+
}
|
497 |
+
|
498 |
+
$options = $field['data'];
|
499 |
+
$id = $field['id'];
|
500 |
+
return static::getSelectHtml( array_combine($options, $options), array(
|
501 |
+
'id' => $this->getIdPrefix($id),
|
502 |
+
'name' => static::getNameHtml(array($this->getMainOptionName(), $id)),
|
503 |
+
'selected' => $field['value']
|
504 |
+
)) .
|
505 |
+
$this->getPlugin()->getTooltips()->doTooltip($id);
|
506 |
+
}
|
507 |
+
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Add settings fields and sections
|
511 |
+
*
|
512 |
+
* @since 4.8.1
|
513 |
+
* @param string $activeTab The slug of the active wprss settings tab.
|
514 |
+
*/
|
515 |
+
public function _renderSettingsPage($activeTab)
|
516 |
+
{
|
517 |
+
$optionName = $this->getMainOptionName();
|
518 |
+
if ($activeTab !== $this->getTabSlug()) return;
|
519 |
+
// Render all sections for this page
|
520 |
+
settings_fields($optionName);
|
521 |
+
do_settings_sections($optionName);
|
522 |
+
}
|
523 |
+
|
524 |
+
/**
|
525 |
+
* Gets the ID prefix, or a prefixed ID.
|
526 |
+
*
|
527 |
+
* IDs are something that can be used in HTML's "id" attributes, or
|
528 |
+
* other internal IDs.
|
529 |
+
*
|
530 |
+
* This can be set via the ID_PREFIX class constant, overridden with the 'id_prefix' data member,
|
531 |
+
* and defaults to the plugin code, followed by an underscore '_'.
|
532 |
+
*
|
533 |
+
* @since 4.8.1
|
534 |
+
* @param string|null $id An ID to prefix.
|
535 |
+
* @return string The prefix, or prefixed ID.
|
536 |
+
*/
|
537 |
+
public function getIdPrefix($id = null)
|
538 |
+
{
|
539 |
+
$prefix = $this->_getDataOrConst('id_prefix', sprintf('%1$s_', $this->getPluginCode()));
|
540 |
+
return is_null($id)
|
541 |
+
? $prefix
|
542 |
+
: "{$prefix}{$id}";
|
543 |
+
}
|
544 |
+
|
545 |
+
|
546 |
+
/**
|
547 |
+
* Gets the slug prefix, or a prefixed slug.
|
548 |
+
*
|
549 |
+
* Slugs are something that can be used in HTML's "class" or other attributes, or URLs.
|
550 |
+
*
|
551 |
+
* This can be set via the SLUG_PREFIX class constant, overridden with the 'slug_prefix' data member,
|
552 |
+
* and defaults to the plugin code, followed by a dash underscore '-'.
|
553 |
+
*
|
554 |
+
* @since 4.8.1
|
555 |
+
* @param string|null $id A slug to prefix.
|
556 |
+
* @return string The prefix, or prefixed slug.
|
557 |
+
*/
|
558 |
+
public function getSlugPrefix($id = null)
|
559 |
+
{
|
560 |
+
$prefix = $this->_getDataOrConst('slug_prefix', sprintf('%1$s-', $this->getPluginCode()));
|
561 |
+
return is_null($id)
|
562 |
+
? $prefix
|
563 |
+
: "{$prefix}{$id}";
|
564 |
+
}
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Gets a section ID from a section code.
|
568 |
+
*
|
569 |
+
* A section code is something that uniquely identifies a section internally.
|
570 |
+
* A section ID, on the other hand, may contain other characters, and is typically
|
571 |
+
* used on the frontend.
|
572 |
+
*
|
573 |
+
* @since 4.8.1
|
574 |
+
* @param string $code The section code.
|
575 |
+
* @return string The section ID.
|
576 |
+
*/
|
577 |
+
public function getSectionId($code)
|
578 |
+
{
|
579 |
+
$pluginCode = $this->getPluginCode();
|
580 |
+
return "settings_{$pluginCode}_{$code}_section";
|
581 |
+
}
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Gets the code of the plugin.
|
585 |
+
*
|
586 |
+
* @since 4.8.1
|
587 |
+
* @see Core\Plugin\PluginInterface::getCode()
|
588 |
+
* @return string The plugin code.
|
589 |
+
*/
|
590 |
+
public function getPluginCode()
|
591 |
+
{
|
592 |
+
return $this->getPlugin()->getCode();
|
593 |
+
}
|
594 |
+
|
595 |
+
/**
|
596 |
+
* Registers the settings section and fields.
|
597 |
+
*
|
598 |
+
* This should be hooked to something in WP.
|
599 |
+
*
|
600 |
+
* @since 4.8.1
|
601 |
+
*/
|
602 |
+
public function register()
|
603 |
+
{
|
604 |
+
$this->_registerSetting();
|
605 |
+
$sections = $this->getSectionsFields();
|
606 |
+
|
607 |
+
foreach ($sections as $sectionId => $section) {
|
608 |
+
$section['id'] = $sectionId;
|
609 |
+
$this->_registerSection($section);
|
610 |
+
}
|
611 |
+
|
612 |
+
$this->_registerSettingsPage();
|
613 |
+
}
|
614 |
+
|
615 |
+
/**
|
616 |
+
* Retrieves all raw data for all sections.
|
617 |
+
*
|
618 |
+
* @since 4.8.1
|
619 |
+
* @return array All sections, together with their fields.
|
620 |
+
*/
|
621 |
+
abstract protected function _getSectionsFields();
|
622 |
+
|
623 |
+
/**
|
624 |
+
* Retrieves all data for all sections, and their fields.
|
625 |
+
*
|
626 |
+
* This is done once, filtered with prefixed 'settings_fields', and cashed.
|
627 |
+
*
|
628 |
+
* @since 4.8.1
|
629 |
+
* @return array All sections, together with their fields.
|
630 |
+
*/
|
631 |
+
public function getSectionsFields()
|
632 |
+
{
|
633 |
+
if (is_null($this->_sectionsFields)) {
|
634 |
+
$this->_sectionsFields = $this->event('settings_fields', array('sections' => $this->_getSectionsFields()))
|
635 |
+
->getSections();
|
636 |
+
}
|
637 |
+
|
638 |
+
return $this->_sectionsFields;
|
639 |
+
}
|
640 |
+
|
641 |
+
/**
|
642 |
+
* A shortcut for creating callables to use as data sources.
|
643 |
+
*
|
644 |
+
* @since 4.8.1
|
645 |
+
* @param callable $callable The callback that the command represents.
|
646 |
+
* @param array $args The arguments for the callback.
|
647 |
+
* @return \Aventura\Wprss\Core\Model\CommandInterface A new command.
|
648 |
+
*/
|
649 |
+
public function createCommand($callable, $args = array())
|
650 |
+
{
|
651 |
+
return new Command(array(
|
652 |
+
'function' => $callable,
|
653 |
+
'args' => $args
|
654 |
+
));
|
655 |
+
}
|
656 |
+
|
657 |
+
/**
|
658 |
+
* Resolves a command by executing it, and returning the result.
|
659 |
+
*
|
660 |
+
* @since 4.8.1
|
661 |
+
* @param CommandInterface $command The command to resolve.
|
662 |
+
* @return mixed Result of the command.
|
663 |
+
* @throws \Aventura\Wprss\SpinnerChief\Exception
|
664 |
+
*/
|
665 |
+
public function resolveCommand($command, $args = array())
|
666 |
+
{
|
667 |
+
if (!is_callable($command)) {
|
668 |
+
throw $this->exception('Cannot resolve command: Command must be callable');
|
669 |
+
}
|
670 |
+
|
671 |
+
return call_user_func_array($command, $args);
|
672 |
+
}
|
673 |
+
|
674 |
+
/**
|
675 |
+
* Retrieves the value of a datasource, or if not a datasource just returns it.
|
676 |
+
*
|
677 |
+
* @since 4.8.1
|
678 |
+
* @param callable $source The datasource.
|
679 |
+
* @param array $args Additional arguments for the datasource.
|
680 |
+
* @return mixed The resolved datasource value.
|
681 |
+
*/
|
682 |
+
public function resolveDataSource($source, $args = array())
|
683 |
+
{
|
684 |
+
if (is_callable($source)) {
|
685 |
+
return $this->resolveCommand($source, $args);
|
686 |
+
}
|
687 |
+
|
688 |
+
return $source;
|
689 |
+
}
|
690 |
+
|
691 |
+
/**
|
692 |
+
* Cretes a datasource for retrieving data from this instance.
|
693 |
+
*
|
694 |
+
* @since 4.8.1
|
695 |
+
* @param string $key The key of the data member to retrieve.
|
696 |
+
* @return CommandInterface A command that retrieves data from this instance.
|
697 |
+
*/
|
698 |
+
public function createLocalDataSource($key)
|
699 |
+
{
|
700 |
+
return $this->createCommand(array($this, 'getData'), array($key));
|
701 |
+
}
|
702 |
+
|
703 |
+
/**
|
704 |
+
* Generates HTML of a checkbox based on the passed parameters.
|
705 |
+
*
|
706 |
+
* @since 4.8.1
|
707 |
+
* @see PRSS_FTP_Utils::boolean_to_checkbox()
|
708 |
+
* @param bool|mixed $isChecked Whether or not this checkbox should be ticked.
|
709 |
+
* @param array $args Additional checkbox params.
|
710 |
+
* @param bool $autoEval If true, the first value will be evaluated and compared to known 'true' values.
|
711 |
+
* @return string The HTML of a checkbox.
|
712 |
+
*/
|
713 |
+
static public function getCheckboxHtml($isChecked, $args, $autoEval = true)
|
714 |
+
{
|
715 |
+
if ($autoEval) {
|
716 |
+
$isChecked = static::isTrue($isChecked);
|
717 |
+
}
|
718 |
+
return \WPRSS_FTP_Utils::boolean_to_checkbox($isChecked, $args);
|
719 |
+
}
|
720 |
+
|
721 |
+
/**
|
722 |
+
* Get the HTML output of a <select> element.
|
723 |
+
*
|
724 |
+
* @since 4.8.1
|
725 |
+
* @param array $values The select element's options.
|
726 |
+
* @param array $args Data for the select element.
|
727 |
+
* @return string The select element HTML.
|
728 |
+
*/
|
729 |
+
static public function getSelectHtml($values, $args = array())
|
730 |
+
{
|
731 |
+
return \WPRSS_FTP_Utils::array_to_select($values, $args);
|
732 |
+
}
|
733 |
+
|
734 |
+
/**
|
735 |
+
* Get the HTML output of an <input> element of type 'text' or 'password'.
|
736 |
+
*
|
737 |
+
* @since 4.8.1
|
738 |
+
* @param string|int $value The input element's value.
|
739 |
+
* @param array $args Data for the input element.
|
740 |
+
* @return string The input element HTML.
|
741 |
+
*/
|
742 |
+
static public function getTextHtml($value, $args = array())
|
743 |
+
{
|
744 |
+
$defaults = array(
|
745 |
+
'type' => 'text',
|
746 |
+
'class' => '',
|
747 |
+
'placeholder' => isset($args['label']) ? $args['label'] : ''
|
748 |
+
);
|
749 |
+
$args = array_merge_recursive_distinct($defaults, $args);
|
750 |
+
|
751 |
+
return sprintf('<input id="%1$s" type="%2$s" name="%3$s" value="%4$s" class="%5$s" placeholder="%6$s" />',
|
752 |
+
esc_attr($args['id']),
|
753 |
+
$args['type'],
|
754 |
+
$args['name'],
|
755 |
+
esc_attr($value),
|
756 |
+
$args['class'],
|
757 |
+
$args['placeholder']
|
758 |
+
);
|
759 |
+
}
|
760 |
+
|
761 |
+
/**
|
762 |
+
* Get the HTML output of an <input> element of type 'number'.
|
763 |
+
*
|
764 |
+
* @since 4.8.1
|
765 |
+
* @param string|int $value The input element's value.
|
766 |
+
* @param array $args Data for the input element.
|
767 |
+
* @return string The input element HTML.
|
768 |
+
*/
|
769 |
+
static public function getNumberHtml($value, $args = array())
|
770 |
+
{
|
771 |
+
$defaults = array(
|
772 |
+
'type' => 'number',
|
773 |
+
'class' => '',
|
774 |
+
'placeholder' => isset($args['label']) ? $args['label'] : '',
|
775 |
+
'min' => 0,
|
776 |
+
'max' => '',
|
777 |
+
'step' => 1
|
778 |
+
);
|
779 |
+
$args = array_merge_recursive_distinct($defaults, $args);
|
780 |
+
|
781 |
+
return sprintf('<input id="%1$s" type="%2$s" name="%3$s" value="%4$s" class="%5$s" placeholder="%6$s" min="%7$s" max="%8$s" step="%9$s" />',
|
782 |
+
esc_attr($args['id']),
|
783 |
+
$args['type'],
|
784 |
+
$args['name'],
|
785 |
+
esc_attr($value),
|
786 |
+
$args['class'],
|
787 |
+
$args['placeholder'],
|
788 |
+
$args['min'],
|
789 |
+
$args['max'],
|
790 |
+
$args['step']
|
791 |
+
);
|
792 |
+
}
|
793 |
+
|
794 |
+
/**
|
795 |
+
* Gets a value for HTML elements' "name" attribute.
|
796 |
+
*
|
797 |
+
* This attribute can have multiple nested names, or levels, such as:
|
798 |
+
* name[subName][subSubName]
|
799 |
+
*
|
800 |
+
* Given all the levels, it will return the correct value for the attribute.
|
801 |
+
*
|
802 |
+
* @since 4.8.1
|
803 |
+
* @param string|array $name A name with levels separated by '/', or an array of levels.
|
804 |
+
* @return string A value used in HTML elements' "name" attribute.
|
805 |
+
*/
|
806 |
+
static public function getNameHtml($name)
|
807 |
+
{
|
808 |
+
if (!is_array($name)) {
|
809 |
+
$name = explode('/', $name);
|
810 |
+
}
|
811 |
+
|
812 |
+
$mainName = array_shift($name);
|
813 |
+
return $mainName . '[' . implode('][', $name) . ']';
|
814 |
+
}
|
815 |
+
|
816 |
+
/**
|
817 |
+
* Checks whether a value is considered to be 'true' by this class.
|
818 |
+
*
|
819 |
+
* @since 4.8.1
|
820 |
+
* @param mixed $value The value to check.
|
821 |
+
* @return bool True if the value is considered by this class to represent 'true'; false otherwise.
|
822 |
+
*/
|
823 |
+
static public function isTrue($value)
|
824 |
+
{
|
825 |
+
return \WPRSS_FTP_Utils::multiboolean($value) || (trim($value) === static::getTrueValue());
|
826 |
+
}
|
827 |
+
|
828 |
+
/**
|
829 |
+
* Get a value that is considered by this class to be 'true'.
|
830 |
+
*
|
831 |
+
* @since 4.8.1
|
832 |
+
* @return string Returns a string representation of a value that is considered to be 'true' by this class.
|
833 |
+
*/
|
834 |
+
static public function getTrueValue()
|
835 |
+
{
|
836 |
+
return static::TRUE_VALUE;
|
837 |
+
}
|
838 |
+
|
839 |
+
/**
|
840 |
+
* Get a value that is considered by this class to be 'false'.
|
841 |
+
*
|
842 |
+
* @since 4.8.1
|
843 |
+
* @return string Returns a string representation of a value that is considered to be 'false' by this class.
|
844 |
+
*/
|
845 |
+
static public function getFalseValue()
|
846 |
+
{
|
847 |
+
return static::FALSE_VALUE;
|
848 |
+
}
|
849 |
+
|
850 |
+
/**
|
851 |
+
* Retrieve a raw option by name from the database.
|
852 |
+
*
|
853 |
+
* @since 4.8.1
|
854 |
+
* @param string $name The name of the option.
|
855 |
+
* @param bool|mixed $default What to return if the option is not found.
|
856 |
+
* @return mixed The option value.
|
857 |
+
*/
|
858 |
+
static public function getOption($name, $default = false)
|
859 |
+
{
|
860 |
+
return get_option($name, $default);
|
861 |
+
}
|
862 |
+
}
|
includes/Aventura/Wprss/Core/Model/SettingsInterface.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Something that can represent settings.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface SettingsInterface
|
11 |
+
{
|
12 |
+
public function validate($settings);
|
13 |
+
|
14 |
+
public function getSectionsFields();
|
15 |
+
|
16 |
+
public function getData();
|
17 |
+
}
|
includes/Aventura/Wprss/Core/Model/SpinnerAbstract.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Common functionality for spinners.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
abstract class SpinnerAbstract extends Core\Plugin\ComponentAbstract implements SpinnerInterface
|
13 |
+
{
|
14 |
+
public function spin($content, $options = array())
|
15 |
+
{
|
16 |
+
$this->getApi()->spin($content, $options);
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @since 4.8.1
|
21 |
+
* @return SpinnerApiInterface
|
22 |
+
*/
|
23 |
+
abstract public function getApi();
|
24 |
+
}
|
includes/Aventura/Wprss/Core/Model/SpinnerApiAbstract.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
abstract class SpinnerApiAbstract extends Core\Plugin\ComponentAbstract implements SpinnerApiInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Spins content using a remote API.
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
* @param mixed $content
|
17 |
+
* @param array $options Options for spinning.
|
18 |
+
* @return mixed
|
19 |
+
*/
|
20 |
+
public function spin($content, $options = array())
|
21 |
+
{
|
22 |
+
$uri = $this->getQueryUri($options);
|
23 |
+
$response = $this->query($uri, $content, $options);
|
24 |
+
|
25 |
+
return $response;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Happens immediately before the spin request is sent to the remote API.
|
30 |
+
*
|
31 |
+
* @since 4.8.1
|
32 |
+
* @param mixed $request The request that is about to be sent.
|
33 |
+
* @param string $uri The URI, to which the request is about to be sent.
|
34 |
+
* @return mixed The new request, possibly modified
|
35 |
+
*/
|
36 |
+
protected function _beforeQuery($request, $uri = null)
|
37 |
+
{
|
38 |
+
return $request;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Happens immediately after the spin request is sent to the remote API.
|
43 |
+
*
|
44 |
+
* @since 4.8.1
|
45 |
+
* @param mixed $response The response that was received.
|
46 |
+
* @param string $uri The URI, to which the request was sent.
|
47 |
+
* @return mixed The new response, possibly modified
|
48 |
+
*/
|
49 |
+
protected function _afterQuery($response, $uri = null)
|
50 |
+
{
|
51 |
+
return $response;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Sends the spinning query to the remote API.
|
56 |
+
*
|
57 |
+
* @since 4.8.1
|
58 |
+
* @param string $uri The URI to send the query to.
|
59 |
+
* @param mixed $request The request to send.
|
60 |
+
* @return mixed The query response.
|
61 |
+
*/
|
62 |
+
public function query($uri, $request, $options = array())
|
63 |
+
{
|
64 |
+
$request = $this->_beforeQuery($request, $uri);
|
65 |
+
$response = $this->_sendRequest($uri, $request);
|
66 |
+
$response = $this->_afterQuery($response, $uri);
|
67 |
+
|
68 |
+
return $response;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Does the actual sending of the request.
|
73 |
+
*
|
74 |
+
* @since 4.8.1
|
75 |
+
* @return mixed The low-level API response.
|
76 |
+
*/
|
77 |
+
abstract protected function _sendRequest($uri, $request);
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Get the actual URI, to which the spin request will be sent.
|
81 |
+
*
|
82 |
+
* @since 4.8.1
|
83 |
+
* @return string The complete URI, to which a spin request should be sent.
|
84 |
+
*/
|
85 |
+
abstract public function getQueryUri($options = array());
|
86 |
+
}
|
includes/Aventura/Wprss/Core/Model/SpinnerApiInterface.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Something that can spin content, usually using a remote service.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface SpinnerApiInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Spins the content using the remote API.
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
* @param mixed $content The content to spin.
|
17 |
+
* @param array $options Options for spinning.
|
18 |
+
*/
|
19 |
+
public function spin($content, $options = array());
|
20 |
+
}
|
includes/Aventura/Wprss/Core/Model/SpinnerInterface.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Model;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* An interface of something that can spin post data.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface SpinnerInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
*
|
14 |
+
* @since 4.8.1
|
15 |
+
* @param string $content
|
16 |
+
*/
|
17 |
+
public function spin($content);
|
18 |
+
}
|
includes/Aventura/Wprss/Core/Plugin.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* A dummy plugin for the Core plugin.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
* @todo Create real Core plugin in the Core plugin.
|
10 |
+
*/
|
11 |
+
class Plugin extends Plugin\PluginAbstract
|
12 |
+
{
|
13 |
+
const CODE = 'wprss';
|
14 |
+
const VERSION = WPRSS_VERSION;
|
15 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/AddonAbstract.php
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* A base class for SpinnerChief add-ons.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
abstract class AddonAbstract extends PluginAbstract implements AddonInterface, ComponentInterface
|
11 |
+
{
|
12 |
+
/** @since 4.8.1 */
|
13 |
+
protected $_parent;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* {@inheritdoc}
|
17 |
+
*
|
18 |
+
* @since 4.8.1
|
19 |
+
*/
|
20 |
+
public function __construct($data, PluginInterface $parent, ComponentFactoryInterface $factory = null)
|
21 |
+
{
|
22 |
+
parent::__construct($data, $factory);
|
23 |
+
$this->_setParent($parent);
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* {@inheritdoc}
|
28 |
+
*
|
29 |
+
* @since 4.8.1
|
30 |
+
*/
|
31 |
+
public function getPlugin()
|
32 |
+
{
|
33 |
+
return $this->getParent();
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* {@inheritdoc}
|
38 |
+
*
|
39 |
+
* @since 4.8.1
|
40 |
+
*/
|
41 |
+
public function getParent() {
|
42 |
+
return $this->_parent;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* {@inheritdoc}
|
47 |
+
*
|
48 |
+
* @since 4.8.1
|
49 |
+
*/
|
50 |
+
protected function _setParent(PluginInterface $parent) {
|
51 |
+
$this->_parent = $parent;
|
52 |
+
return $this;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* {@inheritdoc}
|
57 |
+
*
|
58 |
+
* @since 4.8.1
|
59 |
+
*/
|
60 |
+
public function getLogger()
|
61 |
+
{
|
62 |
+
if ($logger = parent::getLogger()) {
|
63 |
+
return $logger;
|
64 |
+
}
|
65 |
+
|
66 |
+
return $this->getParent()->getLogger();
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* {@inheritdoc}
|
71 |
+
*
|
72 |
+
* @since 4.8.1
|
73 |
+
*/
|
74 |
+
public function getEventManager()
|
75 |
+
{
|
76 |
+
if ($events = parent::getEventManager()) {
|
77 |
+
return $events;
|
78 |
+
}
|
79 |
+
|
80 |
+
return $this->getParent()->getEventManager();
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* {@inheritdoc}
|
85 |
+
*
|
86 |
+
* @since 4.8.1
|
87 |
+
*/
|
88 |
+
public function getEventPrefix($name = null)
|
89 |
+
{
|
90 |
+
$prefix = '';
|
91 |
+
$prefix .= $this->getParent()->getEventPrefix();
|
92 |
+
$prefix .= parent::getEventPrefix();
|
93 |
+
if (is_null($name)) {
|
94 |
+
return $prefix;
|
95 |
+
}
|
96 |
+
$prefix = static::stringHadPrefix($name)
|
97 |
+
? $name
|
98 |
+
: "{$prefix}{$name}";
|
99 |
+
|
100 |
+
return $prefix;
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* {@inheritdoc}
|
105 |
+
*
|
106 |
+
* @since 4.8.1
|
107 |
+
*/
|
108 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null)
|
109 |
+
{
|
110 |
+
if (is_string($listener) && !is_object($listener)) {
|
111 |
+
$listener = array($this, $listener);
|
112 |
+
}
|
113 |
+
|
114 |
+
return parent::on($name, $listener, $data, $priority, $acceptedArgs);
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* {@inheritdoc}
|
119 |
+
*
|
120 |
+
* @since 4.8.1
|
121 |
+
*/
|
122 |
+
public function event($name, $data = array())
|
123 |
+
{
|
124 |
+
if (!isset($data['caller'])) {
|
125 |
+
$data['caller'] = $this;
|
126 |
+
}
|
127 |
+
|
128 |
+
return parent::event($name, $data);
|
129 |
+
}
|
130 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/AddonFactoryAbstract.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Common functionality for add-on factories.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
abstract class AddonFactoryAbstract extends FactoryAbstract implements AddonFactoryInterface
|
11 |
+
{
|
12 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/AddonFactoryInterface.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* An interface for something that creates add-ons.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface AddonFactoryInterface extends FactoryInterface
|
11 |
+
{
|
12 |
+
|
13 |
+
/**
|
14 |
+
* {@inheritdoc}
|
15 |
+
*
|
16 |
+
* @since 4.8.1
|
17 |
+
* @return AddonInterface
|
18 |
+
*/
|
19 |
+
static public function create();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Get the parent of the add-ons created by this interface.
|
23 |
+
*
|
24 |
+
* @since 4.8.1
|
25 |
+
* @return PluginInterface
|
26 |
+
*/
|
27 |
+
public function getParent();
|
28 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/AddonInterface.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @since 4.8.1
|
7 |
+
*/
|
8 |
+
interface AddonInterface extends PluginInterface
|
9 |
+
{
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Get the plugin, for which this is an add-on.
|
13 |
+
*
|
14 |
+
* @since 4.8.1
|
15 |
+
* @return PluginInterface The parent plugin instance.
|
16 |
+
*/
|
17 |
+
public function getParent();
|
18 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/ComponentAbstract.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* A base class for all SpinnerChief add-on components.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
abstract class ComponentAbstract extends Core\Model\ModelAbstract implements ComponentInterface
|
13 |
+
{
|
14 |
+
/**
|
15 |
+
* @var PluginInterface The plugin, to which this component belongs
|
16 |
+
* @since 4.8.1
|
17 |
+
*/
|
18 |
+
protected $_plugin;
|
19 |
+
|
20 |
+
/**
|
21 |
+
*
|
22 |
+
* @since 4.8.1
|
23 |
+
* @param PluginInterface|array $data The instance of the
|
24 |
+
* add-on, of which this is to be a component. Alternatively, an array with data, which must have the 'plugin'
|
25 |
+
* index set to that instance.
|
26 |
+
*/
|
27 |
+
public function __construct($data)
|
28 |
+
{
|
29 |
+
// Allowing specifying parent as the only argument
|
30 |
+
if (!is_array($data)) {
|
31 |
+
$data = array('plugin' => $data);
|
32 |
+
}
|
33 |
+
// Making sure the parent is specified
|
34 |
+
if (!isset($data['plugin']) || !($data['plugin'] instanceof PluginInterface)) {
|
35 |
+
throw $this->exception(array('Could not create component: The "%1$s" index must be a plugin instance'), array(__NAMESPACE__, 'Exception'));
|
36 |
+
}
|
37 |
+
$plugin = $data['plugin'];
|
38 |
+
unset($data['plugin']);
|
39 |
+
|
40 |
+
$this->_plugin = $plugin;
|
41 |
+
parent::__construct($data);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* {@inheritdoc}
|
46 |
+
*
|
47 |
+
* @since 4.8.1
|
48 |
+
* @return PluginInterface
|
49 |
+
*/
|
50 |
+
public function getPlugin()
|
51 |
+
{
|
52 |
+
return $this->_plugin;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Sets the parent plugin for this component.
|
57 |
+
*
|
58 |
+
* @since 4.8.1
|
59 |
+
* @param PluginInterface $plugin The plugin to set.
|
60 |
+
* @return ComponentAbstract This instance.
|
61 |
+
*/
|
62 |
+
protected function _setPlugin(PluginInterface $plugin) {
|
63 |
+
$this->_plugin = $plugin;
|
64 |
+
return $this;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Get the text domain of this component.
|
69 |
+
*
|
70 |
+
* @since 4.8.1
|
71 |
+
* @return string The text domain.
|
72 |
+
*/
|
73 |
+
public function getTextDomain() {
|
74 |
+
return $this->getPlugin()->getTextDomain();
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Creates an exception, the root of which is the parent plugin.
|
79 |
+
*
|
80 |
+
* @since 4.8.1
|
81 |
+
* @return Core\Exception
|
82 |
+
*/
|
83 |
+
public function exception($text, $className = null, $translate = null)
|
84 |
+
{
|
85 |
+
return $this->getPlugin()->exception($text, $className, $translate);
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Hooks this component into the environment.
|
90 |
+
*
|
91 |
+
* Typically, this is done by a factory upon creation, but not necessarily.
|
92 |
+
* Override this to hook in your component.
|
93 |
+
*
|
94 |
+
* @since 4.8.1
|
95 |
+
*/
|
96 |
+
public function hook() {}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Gets a hook name prefix, or a prefixed hook name.
|
100 |
+
*
|
101 |
+
* A hook prefix is used by all abstracted methods for adding hooks.
|
102 |
+
* The prefix defaults to the plugin's prefix. If none set, the plugin code followed by an underscore '_'.
|
103 |
+
* If can be additionally defined as the HOOK_PREFIX class constant, and overridden
|
104 |
+
* with the 'hook_prefix' data member.
|
105 |
+
*
|
106 |
+
* @since 4.8.1
|
107 |
+
* @param string $code A hook name to prefix.
|
108 |
+
* @return string The hook prefix, or prefixed string.
|
109 |
+
*/
|
110 |
+
public function getEventPrefix($code = null)
|
111 |
+
{
|
112 |
+
$prefix = $this->_getDataOrConst('hook_prefix');
|
113 |
+
if (is_null($prefix)) {
|
114 |
+
$prefix = $this->getPlugin()->getHookPrefix();
|
115 |
+
}
|
116 |
+
if (is_null($prefix)) {
|
117 |
+
$prefix = sprintf('%1$s_', $this->getPluginCode());
|
118 |
+
}
|
119 |
+
|
120 |
+
return is_null($code)
|
121 |
+
? $prefix
|
122 |
+
: "{$prefix}{$code}";
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* {@inheritdoc}
|
127 |
+
*
|
128 |
+
* @since 4.8.1
|
129 |
+
* @see Core\Model\LoggerInterface
|
130 |
+
* @param string|int $level
|
131 |
+
* @param string $message
|
132 |
+
* @param array $context Particularly, the 'source' index should point to the function/method,
|
133 |
+
* where the message is sent from.
|
134 |
+
* @return bool True if log entry was processed; false otherwise.
|
135 |
+
*/
|
136 |
+
public function log($level, $message, array $context = array())
|
137 |
+
{
|
138 |
+
return $this->getPlugin()->log($level, $message, $context);
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* {@inheritdoc}
|
143 |
+
*
|
144 |
+
* @since 4.8.1
|
145 |
+
*/
|
146 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null)
|
147 |
+
{
|
148 |
+
if (is_string($listener) && !is_object($listener)) {
|
149 |
+
$listener = array($this, $listener);
|
150 |
+
}
|
151 |
+
|
152 |
+
return $this->getPlugin()->on($name, $listener, $data, $priority, $acceptedArgs);
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* {@inheritdoc}
|
157 |
+
*
|
158 |
+
* @since 4.8.1
|
159 |
+
*/
|
160 |
+
public function event($name, $data = array())
|
161 |
+
{
|
162 |
+
if (!isset($data['caller'])) {
|
163 |
+
$data['caller'] = $this;
|
164 |
+
}
|
165 |
+
|
166 |
+
return $this->getPlugin()->event($name, $data);
|
167 |
+
}
|
168 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/ComponentFactoryAbstract.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Common functionality of component factories.
|
7 |
+
* A component factory is also a component ;P
|
8 |
+
*
|
9 |
+
* @since 4.8.1
|
10 |
+
*/
|
11 |
+
abstract class ComponentFactoryAbstract extends ComponentAbstract implements ComponentFactoryInterface
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Creates a new component instance.
|
15 |
+
*
|
16 |
+
* @since 4.8.1
|
17 |
+
* @param string $class The classname of the component to create.
|
18 |
+
* Can be relative to the base namespace of this factory.
|
19 |
+
* @param PluginInterface $parent The parent plugin for the new component.
|
20 |
+
* @return ComponentInterface A new component.
|
21 |
+
* @throws Exception If class does not exist, or is not a component class.
|
22 |
+
*/
|
23 |
+
public function createComponent($class, PluginInterface $parent, array $data = array())
|
24 |
+
{
|
25 |
+
$className = $this->getComponentClassName($class);
|
26 |
+
$componentBase = 'Aventura\Wprss\Core\Plugin\ComponentInterface';
|
27 |
+
if (!static::classImplements($className, $componentBase)) {
|
28 |
+
throw $this->exception(array('Could not create component: "%1$s" is not a component class as it does not implement "%2$s"', $className, $componentBase), array(__NAMESPACE__, 'Exception'));
|
29 |
+
}
|
30 |
+
|
31 |
+
if (!class_exists($className)) {
|
32 |
+
throw $this->exception(array('Could not create component: component class"%1$s" does not exist', $className), array(__NAMESPACE__, 'Exception'));
|
33 |
+
}
|
34 |
+
|
35 |
+
$data['plugin'] = $parent;
|
36 |
+
$component = new $className($data);
|
37 |
+
$component->hook();
|
38 |
+
|
39 |
+
return $component;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Get the name of a component class, based on it's relative or absolute name, or mapped ID.
|
44 |
+
*
|
45 |
+
* @since 4.8.1
|
46 |
+
* @param string $className A relative or absolute class name, or some other class identifier that is mapped
|
47 |
+
* to a class name. If relative, then relative to the {@see getBaseNamespace()}.
|
48 |
+
* @return string Name of the component class.
|
49 |
+
*/
|
50 |
+
public function getComponentClassName($className)
|
51 |
+
{
|
52 |
+
// Namespace specified as array of parts; assume root namespace
|
53 |
+
if (is_array($className)) {
|
54 |
+
$className = '\\' . trim(implode('\\', $className), '\\');
|
55 |
+
}
|
56 |
+
|
57 |
+
if (static::isRootNamespace($className)) {
|
58 |
+
return $className;
|
59 |
+
}
|
60 |
+
|
61 |
+
$rootNamespace = $this->getBaseNamespace();
|
62 |
+
return sprintf('%1$s\\%2$s', $rootNamespace, $className);
|
63 |
+
}
|
64 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/ComponentFactoryInterface.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Something that allows creation and initialization of SpinnerChief classes.
|
7 |
+
*/
|
8 |
+
interface ComponentFactoryInterface
|
9 |
+
{
|
10 |
+
public function createComponent($class, PluginInterface $parent);
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @return string The base namespace, to which components created by this factory will belong.
|
14 |
+
*/
|
15 |
+
public function getBaseNamespace();
|
16 |
+
|
17 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/ComponentInterface.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Something that can be a plugin component.
|
9 |
+
*
|
10 |
+
* A plugin component is something that is a part of a plugin, and therefore
|
11 |
+
* interacts with the plugin's main class, i.e. depends on it.
|
12 |
+
*
|
13 |
+
* @since 4.8.1
|
14 |
+
*/
|
15 |
+
interface ComponentInterface
|
16 |
+
{
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Get this component's plugin;
|
20 |
+
*
|
21 |
+
* @since 4.8.1
|
22 |
+
* @return \Aventura\Wprss\Core\Plugin\PluginInterface The instance of the add-on,
|
23 |
+
* of which this is a component.
|
24 |
+
*/
|
25 |
+
public function getPlugin();
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Allows the environment to cause this plugin to hook itself into the environment.
|
29 |
+
*
|
30 |
+
* Called by the environment at a time that is determined to be suitable for the environment.
|
31 |
+
*
|
32 |
+
* @since 4.8.1
|
33 |
+
*/
|
34 |
+
public function hook();
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @since 4.8.1
|
38 |
+
* @see Core\Model\LoggerInterface
|
39 |
+
*/
|
40 |
+
public function log($level, $message, array $context = array());
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Listen to an event.
|
44 |
+
*
|
45 |
+
* @since 4.8.1
|
46 |
+
* @param string $name The name of the event to listen for.
|
47 |
+
* @param callable|string $listener The listener for the event. If string given, the method of this instane
|
48 |
+
* with that name will be used.
|
49 |
+
* @param array|null $data Additional arguments to pass to the event.
|
50 |
+
* @param int|null $priority Priority of the listener. If null, implementation-default will be used.
|
51 |
+
* @param int|null $acceptedArgs Number of the args passed to the listener. If null, implementation-default is used.
|
52 |
+
* @return bool True if listener registered; false otherwise.
|
53 |
+
*/
|
54 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null);
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Raise an event.
|
58 |
+
*
|
59 |
+
* @since 4.8.1
|
60 |
+
* @param string $name Name of the event.
|
61 |
+
* @param array|object $data The event data.
|
62 |
+
* @return EventInterface|null An event object that is the result of this event.
|
63 |
+
* This object will contain the data passed, and possibly modified.
|
64 |
+
* If event cannot be raised, null is returned.
|
65 |
+
*/
|
66 |
+
public function event($name, $data = array());
|
67 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/Exception.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* The base class for all WP plugins.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
class Exception extends Core\Exception
|
13 |
+
{
|
14 |
+
//put your code here
|
15 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/FactoryAbstract.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
abstract class FactoryAbstract extends Core\Model\ModelAbstract implements FactoryInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Creates an instance of this class.
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
* @param array $data Data for the new instance.
|
17 |
+
* @return FactoryAbstract
|
18 |
+
*/
|
19 |
+
static protected function _getInstance($data = array())
|
20 |
+
{
|
21 |
+
return new static($data);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* {@inheritdoc}
|
26 |
+
*
|
27 |
+
* @since 4.8.1
|
28 |
+
* @param type $parent
|
29 |
+
* @param array|string $data Data for the new plugin. If string given, it will be assumed the value of the
|
30 |
+
* 'basename' index.
|
31 |
+
* @return PluginInterface
|
32 |
+
*/
|
33 |
+
static public function create($data = array())
|
34 |
+
{
|
35 |
+
$me = static::_getInstance();
|
36 |
+
do_action('wprss_plugin_factory_create_plugin_before', $me);
|
37 |
+
$addon = $me->_create($data);
|
38 |
+
do_action('wprss_plugin_factory_create_plugin_after', $addon, $me);
|
39 |
+
|
40 |
+
return $addon;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Does the actual creation.
|
45 |
+
*
|
46 |
+
* @since 4.8.1
|
47 |
+
* @return PluginInterface
|
48 |
+
*/
|
49 |
+
abstract protected function _create($data);
|
50 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/FactoryInterface.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* An interface for something that creates plugins.
|
7 |
+
*
|
8 |
+
* @since 4.8.1
|
9 |
+
*/
|
10 |
+
interface FactoryInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Create a plugin.
|
14 |
+
*
|
15 |
+
* @since 4.8.1
|
16 |
+
* @return PluginInterface
|
17 |
+
*/
|
18 |
+
static public function create();
|
19 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/PluginAbstract.php
ADDED
@@ -0,0 +1,359 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* The base class for all WP plugins.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
|
13 |
+
{
|
14 |
+
const CODE = '';
|
15 |
+
const VERSION = '';
|
16 |
+
|
17 |
+
/** @since 4.8.1 */
|
18 |
+
protected $_factory;
|
19 |
+
/** @since 4.8.1 */
|
20 |
+
protected $_logger;
|
21 |
+
/** @since 4.8.1 */
|
22 |
+
protected $_eventManager;
|
23 |
+
|
24 |
+
/**
|
25 |
+
*
|
26 |
+
* @param array|string $data Data that describes the plugin.
|
27 |
+
* The following indices are required:
|
28 |
+
* * `basename` - The plugin basename, or full path to plugin's main file. See {@see getBasename()}.
|
29 |
+
* Other indices explicitly handled by this class:
|
30 |
+
* * `component_factory` - Instance or name of a component factory class.
|
31 |
+
* * `text_domain` - The text domain used for translation by this plugin. See {@see getTextDomain}.
|
32 |
+
* * `name` - The human-readable name of the plugin. See {@see getName()}.
|
33 |
+
* Any other data will just be added to this instances internal data.
|
34 |
+
* @param ComponentFactoryInterface A factory that will create components for this plugin.
|
35 |
+
*
|
36 |
+
* @throws Exception If required fields are not specified.
|
37 |
+
*/
|
38 |
+
public function __construct($data, ComponentFactoryInterface $factory = null)
|
39 |
+
{
|
40 |
+
if (!is_array($data)) {
|
41 |
+
$data = array('basename' => $data);
|
42 |
+
}
|
43 |
+
|
44 |
+
// Handling basename
|
45 |
+
if (!isset($data['basename'])) {
|
46 |
+
throw $this->exception('Could not create plugin instance: "basename" must be specified', array(__NAMESPACE__, 'Exception'));
|
47 |
+
}
|
48 |
+
$basename = trim($data['basename']);
|
49 |
+
|
50 |
+
// Account for full path to main file.
|
51 |
+
if (substr($basename, 0, 1) === '/' || substr_count($basename, '/') >= 2) {
|
52 |
+
$basename = static::getPluginBasename($basename);
|
53 |
+
}
|
54 |
+
$data['basename'] = $basename;
|
55 |
+
|
56 |
+
// Normalizing and setting component factory
|
57 |
+
if (is_null($factory) && isset($data['component_factory'])) {
|
58 |
+
$factory = $data['component_factory'];
|
59 |
+
}
|
60 |
+
|
61 |
+
if ($factory) {
|
62 |
+
$this->setFactory($factory);
|
63 |
+
}
|
64 |
+
$this->setBasename($basename);
|
65 |
+
|
66 |
+
parent::__construct($data);
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getBasename()
|
70 |
+
{
|
71 |
+
return $this->getData('basename');
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getTextDomain()
|
75 |
+
{
|
76 |
+
return $this->getData('text_domain');
|
77 |
+
}
|
78 |
+
|
79 |
+
public function getName()
|
80 |
+
{
|
81 |
+
return $this->getData('name');
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getCode()
|
85 |
+
{
|
86 |
+
return $this->_getDataOrConst('code');
|
87 |
+
}
|
88 |
+
|
89 |
+
public function getVersion()
|
90 |
+
{
|
91 |
+
return $this->_getDataOrConst('version');
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @since 4.8.1
|
96 |
+
* @return ComponentFactoryInterface
|
97 |
+
*/
|
98 |
+
public function getFactory()
|
99 |
+
{
|
100 |
+
return $this->_factory;
|
101 |
+
}
|
102 |
+
|
103 |
+
public function setFactory(ComponentFactoryInterface $factory)
|
104 |
+
{
|
105 |
+
$this->_setFactory($factory);
|
106 |
+
return $this;
|
107 |
+
}
|
108 |
+
|
109 |
+
public function isActive()
|
110 |
+
{
|
111 |
+
return static::isPluginActive($this);
|
112 |
+
}
|
113 |
+
|
114 |
+
public function deactivate()
|
115 |
+
{
|
116 |
+
static::deactivatePlugin($this);
|
117 |
+
return $this;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Checks if a plugin is active.
|
122 |
+
*
|
123 |
+
* @since 4.8.1
|
124 |
+
* @param PluginInterface|string $plugin A plugin instance or basename.
|
125 |
+
* @return bool True if the plugin is active; false otherwise.
|
126 |
+
*/
|
127 |
+
static public function isPluginActive($plugin)
|
128 |
+
{
|
129 |
+
static::_ensurePluginFunctionsExist();
|
130 |
+
|
131 |
+
if ($plugin instanceof PluginInterface) {
|
132 |
+
$plugin = $plugin->getBasename();
|
133 |
+
}
|
134 |
+
|
135 |
+
return is_plugin_active($plugin);
|
136 |
+
}
|
137 |
+
|
138 |
+
static public function deactivatePlugin($plugin)
|
139 |
+
{
|
140 |
+
static::_ensurePluginFunctionsExist();
|
141 |
+
|
142 |
+
if ($plugin instanceof PluginInterface) {
|
143 |
+
$plugin = $plugin->getBasename();
|
144 |
+
}
|
145 |
+
|
146 |
+
deactivate_plugins($plugin);
|
147 |
+
}
|
148 |
+
|
149 |
+
static protected function _ensurePluginFunctionsExist()
|
150 |
+
{
|
151 |
+
// Making sure there are the functions we need
|
152 |
+
if (!function_exists( 'is_plugin_active' )) {
|
153 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Sets the component factory instance.
|
159 |
+
*
|
160 |
+
* If class name given instead, it will be instantiated.
|
161 |
+
*
|
162 |
+
* @since 4.8.1
|
163 |
+
* @param ComponentFactoryInterface|string $factory The component factory instance or class name.
|
164 |
+
* @return PluginInterface This instance.
|
165 |
+
* @throws Exception If factory class specified as classname string does not exist, or is not a factory.
|
166 |
+
*/
|
167 |
+
protected function _setFactory(ComponentFactoryInterface $factory) {
|
168 |
+
// Factory could be a classname
|
169 |
+
if (is_string($factory)) {
|
170 |
+
// Making sure it exists
|
171 |
+
$factory = trim($factory);
|
172 |
+
if (!class_exists($factory)) {
|
173 |
+
throw $this->exception(array('Could not set component factory: Factory class "%1$s" does not exist', $factory), array(__NAMESPACE__, 'Exception'));
|
174 |
+
}
|
175 |
+
// Making sure it's a factory
|
176 |
+
if (!is_a($factory, __NAMESPACE__ . '\ComponentFactoryInterface')) {
|
177 |
+
throw $this->exception(array('Could not set component factory: Factory class "%1$s" is not a factory', $factory), array(__NAMESPACE__, 'Exception'));
|
178 |
+
}
|
179 |
+
|
180 |
+
$factory = new $factory();
|
181 |
+
/* @var $factory Aventura\Wprss\Core\Plugin\ComponentFactoryInterface */
|
182 |
+
}
|
183 |
+
|
184 |
+
$this->_factory = $factory;
|
185 |
+
return $this;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Translates some text.
|
190 |
+
*
|
191 |
+
* @since [*next-version*]s
|
192 |
+
* @param string $text The text to translate.
|
193 |
+
* @param string|null The text domain to use for translation.
|
194 |
+
* Defaults to this plugin's text domain.
|
195 |
+
* @return string Translated text
|
196 |
+
*/
|
197 |
+
protected function _translate($text, $translator = null)
|
198 |
+
{
|
199 |
+
if (!is_null($translator)) {
|
200 |
+
$translator = $this->getTextDomain();
|
201 |
+
}
|
202 |
+
|
203 |
+
return __($text, $translator);
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Gets a plugin basename from its absolute path.
|
208 |
+
*
|
209 |
+
* @since 4.8.1
|
210 |
+
* @param string $path Absolute path to a plugin's main file.
|
211 |
+
* @return string The path to the plugin's main file, relative to the plugins directory.
|
212 |
+
*/
|
213 |
+
public static function getPluginBasename($path) {
|
214 |
+
return plugin_basename($path);
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Gets the logger instance used by this plugin.
|
219 |
+
*
|
220 |
+
* @since 4.8.1
|
221 |
+
* @return Core\Model\LoggerInterface|null
|
222 |
+
*/
|
223 |
+
public function getLogger()
|
224 |
+
{
|
225 |
+
return $this->_logger;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Sets the logger instance to be used by this plugin.
|
230 |
+
*
|
231 |
+
* @since 4.8.1
|
232 |
+
* @param Core\Model\LoggerInterface $logger
|
233 |
+
* @return Core\Plugin\PluginAbstract
|
234 |
+
*/
|
235 |
+
public function setLogger(Core\Model\LoggerInterface $logger)
|
236 |
+
{
|
237 |
+
$this->_logger = $logger;
|
238 |
+
return $this;
|
239 |
+
}
|
240 |
+
|
241 |
+
public function log($level, $message, array $context = array())
|
242 |
+
{
|
243 |
+
$isFormattable = is_array($message) && isset($message[0]) && is_string($message[0]);
|
244 |
+
if (is_object($message) || empty($message) || (!is_string($message) && !$isFormattable)) {
|
245 |
+
return $this->logObject($level, $message, $context);
|
246 |
+
}
|
247 |
+
|
248 |
+
if ($logger = $this->getLogger()) {
|
249 |
+
try {
|
250 |
+
$message = $this->__($message);
|
251 |
+
} catch (\InvalidArgumentException $e) {
|
252 |
+
return $this->logObject($level, $message, $context);
|
253 |
+
}
|
254 |
+
return $logger->log($level, $message, $context);
|
255 |
+
}
|
256 |
+
|
257 |
+
return false;
|
258 |
+
}
|
259 |
+
|
260 |
+
public function logObject($level, $object, array $context = array())
|
261 |
+
{
|
262 |
+
if (empty($object)) {
|
263 |
+
ob_start();
|
264 |
+
var_dump($object);
|
265 |
+
$dump = ob_get_contents();
|
266 |
+
ob_end_clean();
|
267 |
+
}
|
268 |
+
else {
|
269 |
+
$dump = print_r($object, true);
|
270 |
+
}
|
271 |
+
|
272 |
+
return $this->log($level, $dump, $context);
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* A default no-op implementation. Does nothing. Override in descendants.
|
277 |
+
*
|
278 |
+
* @since 4.8.1
|
279 |
+
*/
|
280 |
+
public function hook() {}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* {@inheritdoc}
|
284 |
+
*
|
285 |
+
* @since 4.8.1
|
286 |
+
*/
|
287 |
+
protected function _getEventPrefix($name = null)
|
288 |
+
{
|
289 |
+
$prefix = $this->hasData('event_prefix')
|
290 |
+
? $this->getData('event_prefix')
|
291 |
+
: ($code = $this->getCode()) ? sprintf('%1$s_', $code) : '';
|
292 |
+
|
293 |
+
return string_had_prefix($name, $this->getPrefixOverride())
|
294 |
+
? $name
|
295 |
+
: "{$prefix}{$name}";
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Sets the event manager for this instance.
|
300 |
+
*
|
301 |
+
* @since 4.8.1
|
302 |
+
* @param Core\Model\Event\EventManagerInterface $manager An event manager.
|
303 |
+
* @return PluginAbstract This instance.
|
304 |
+
*/
|
305 |
+
public function setEventManager(Core\Model\Event\EventManagerInterface $manager)
|
306 |
+
{
|
307 |
+
$this->_eventManager = $manager;
|
308 |
+
return $this;
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* Retrieves this instance's event manager.
|
313 |
+
*
|
314 |
+
* @since 4.8.1
|
315 |
+
* @return Core\Model\Event\EventManagerInterface|null The event manager of this instance, or null if not set.
|
316 |
+
*/
|
317 |
+
public function getEventManager()
|
318 |
+
{
|
319 |
+
return $this->_eventManager;
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* {@inheritdoc}
|
324 |
+
*
|
325 |
+
* @since 4.8.1
|
326 |
+
*/
|
327 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null)
|
328 |
+
{
|
329 |
+
if (is_string($listener) && !is_object($listener)) {
|
330 |
+
$listener = array($this, $listener);
|
331 |
+
}
|
332 |
+
|
333 |
+
if ($events = $this->getEventManager()) {
|
334 |
+
$name = $this->getEventPrefix($name);
|
335 |
+
return $events->on($name, $listener, $data, $priority, $acceptedArgs);
|
336 |
+
}
|
337 |
+
|
338 |
+
return false;
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* {@inheritdoc}
|
343 |
+
*
|
344 |
+
* @since 4.8.1
|
345 |
+
*/
|
346 |
+
public function event($name, $data = array())
|
347 |
+
{
|
348 |
+
if (!isset($data['caller'])) {
|
349 |
+
$data['caller'] = $this;
|
350 |
+
}
|
351 |
+
|
352 |
+
if ($events = $this->getEventManager()) {
|
353 |
+
$name = $this->getEventPrefix($name);
|
354 |
+
return $events->event($name, $data);
|
355 |
+
}
|
356 |
+
|
357 |
+
return null;
|
358 |
+
}
|
359 |
+
}
|
includes/Aventura/Wprss/Core/Plugin/PluginInterface.php
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Aventura\Wprss\Core\Plugin;
|
4 |
+
|
5 |
+
use Aventura\Wprss\Core;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Something that can represent a WP plugin.
|
9 |
+
*
|
10 |
+
* @since 4.8.1
|
11 |
+
*/
|
12 |
+
interface PluginInterface
|
13 |
+
{
|
14 |
+
/**
|
15 |
+
* The plugin's basename, e.g. 'my-plugin/my-plugin.php'.
|
16 |
+
*
|
17 |
+
* @since 4.8.1
|
18 |
+
*/
|
19 |
+
public function getBasename();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* The plugin's text domain.
|
23 |
+
*
|
24 |
+
* This will be used for translation.
|
25 |
+
*
|
26 |
+
* @since 4.8.1
|
27 |
+
*/
|
28 |
+
public function getTextDomain();
|
29 |
+
|
30 |
+
/**
|
31 |
+
* The human-readable name of the plugin.
|
32 |
+
*
|
33 |
+
* @since 4.8.1
|
34 |
+
*/
|
35 |
+
public function getName();
|
36 |
+
|
37 |
+
/**
|
38 |
+
* The unique identifier of the plugin.
|
39 |
+
*
|
40 |
+
* @since 4.8.1
|
41 |
+
*/
|
42 |
+
public function getCode();
|
43 |
+
|
44 |
+
/**
|
45 |
+
* The version number of the plugin.
|
46 |
+
*
|
47 |
+
* @since 4.8.1
|
48 |
+
*/
|
49 |
+
public function getVersion();
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @since 4.8.1
|
53 |
+
* @return ComponentFactoryInterface The factory used by this add-on to create component instances.
|
54 |
+
*/
|
55 |
+
public function getFactory();
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @since 4.8.1
|
59 |
+
* @return bool Whether or not the log entry has been processed
|
60 |
+
*/
|
61 |
+
public function log($level, $message, array $context = array());
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @since 4.8.1
|
65 |
+
* @return Core\Model\LoggerInterface
|
66 |
+
*/
|
67 |
+
public function getLogger();
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Creates an exception instance.
|
71 |
+
*
|
72 |
+
* @since 4.8.1
|
73 |
+
* @param string $text The message text.
|
74 |
+
* @param string $class The class name of the exception to throw.
|
75 |
+
* @param string|null $translate Something that would be used to translate the message.
|
76 |
+
* @return \Exception An exception instance.
|
77 |
+
*/
|
78 |
+
public function exception($text, $class = null, $translate = null);
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Override this, and inside this method hook into the environment
|
82 |
+
*
|
83 |
+
* @since 4.8.1
|
84 |
+
*/
|
85 |
+
public function hook();
|
86 |
+
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Add an event listener.
|
90 |
+
*
|
91 |
+
* @since 4.8.1
|
92 |
+
* @param string $name Event name.
|
93 |
+
* @param callable $listener The event listener.
|
94 |
+
* @param null|array $data Additional data to be passed to event handlers. May not work on native system events.
|
95 |
+
* If the event gets passed data with same names when raised, they will override data passed here.
|
96 |
+
* @param int|null $priority Order priority of the listener. If null, implementation-specific default will be assumed.
|
97 |
+
* @param int|null $acceptedArgs The number of arguments to be passed to the handler. If null,
|
98 |
+
* implementation-specific default will be assumed.
|
99 |
+
*/
|
100 |
+
public function on($name, $listener, $data = null, $priority = null, $acceptedArgs = null);
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Raise an event.
|
104 |
+
*
|
105 |
+
* This triggers all event handlers.
|
106 |
+
*
|
107 |
+
* @since 4.8.1
|
108 |
+
* @param string $name Name of the event to raise
|
109 |
+
* @param array $data The data to pass to the event handlers. This will be passed as the first and only argument.
|
110 |
+
* If additional data members were passed with {@see PluginInterface::on()}, members passed here will override.
|
111 |
+
* @return Core\Model\Event\EventInterface
|
112 |
+
*/
|
113 |
+
public function event($name, $data = array());
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Get the instance of the event manager that the plugin uses.
|
117 |
+
*
|
118 |
+
* @since 4.8.1
|
119 |
+
* @return Core\Model\Event\EventManagerInterface
|
120 |
+
*/
|
121 |
+
public function getEventManager();
|
122 |
+
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Get this instance's event prefix, or a prefixed event name.
|
126 |
+
*
|
127 |
+
* An event prefix is a prefix that will by default be added to names of events
|
128 |
+
* that are listened to or raised by this instance.
|
129 |
+
*
|
130 |
+
* The event prefix is by default the plugin code followed by an underscore "_", unless the code is
|
131 |
+
* not set, in which case the prefix is empty.
|
132 |
+
*
|
133 |
+
* @since 4.8.1
|
134 |
+
* @param string|null $name An event name to prefix.
|
135 |
+
* @return string This instance's event prefix, or a prefixed name.
|
136 |
+
*/
|
137 |
+
public function getEventPrefix($name = null);
|
138 |
+
}
|
includes/admin-addons.php
CHANGED
@@ -8,70 +8,7 @@
|
|
8 |
*/
|
9 |
function wprss_addons_page_display() {
|
10 |
|
11 |
-
$premium =
|
12 |
-
$premium[] = array(
|
13 |
-
'title' => __( "Excerpts & Thumbnails", WPRSS_TEXT_DOMAIN ),
|
14 |
-
'description' => __( "Adds the ability to display thumbnails and excerpts. Perfect for adding some life and color to your feed item display. For more flexibility Feed to Post is a better option.", WPRSS_TEXT_DOMAIN ),
|
15 |
-
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
16 |
-
'active' => is_plugin_active( 'wp-rss-excerpts-thumbnails/wp-rss-excerpts-thumbnails.php' ),
|
17 |
-
'installed_inactive' => wprss_is_plugin_inactive( 'wp-rss-excerpts-thumbnails/wp-rss-excerpts-thumbnails.php' ),
|
18 |
-
'path' => 'wp-rss-excerpts-thumbnails/wp-rss-excerpts-thumbnails.php',
|
19 |
-
'url' => 'http://www.wprssaggregator.com/extension/excerpts-thumbnails/'
|
20 |
-
);
|
21 |
-
$premium[] = array(
|
22 |
-
'title' => __( "Categories", WPRSS_TEXT_DOMAIN ),
|
23 |
-
'description' => __( "Assign categories to your feed sources. Then display a particular category or multiple categories on a post or page via shortcodes.", WPRSS_TEXT_DOMAIN ),
|
24 |
-
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
25 |
-
'active' => is_plugin_active( 'wp-rss-categories/wp-rss-categories.php' ),
|
26 |
-
'installed_inactive' => wprss_is_plugin_inactive( 'wp-rss-categories/wp-rss-categories.php' ),
|
27 |
-
'path' => 'wp-rss-categories/wp-rss-categories.php',
|
28 |
-
'url' => 'http://www.wprssaggregator.com/extension/categories/'
|
29 |
-
);
|
30 |
-
$premium[] = array(
|
31 |
-
'title' => __( "Keyword Filtering", WPRSS_TEXT_DOMAIN ),
|
32 |
-
'description' => __( "Import feeds that contain specific keywords in either the title or their content. Control what gets imported to your blog. You can use keywords, keyphrases and categories.", WPRSS_TEXT_DOMAIN ),
|
33 |
-
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
34 |
-
'active' => is_plugin_active( 'wp-rss-keyword-filtering/wp-rss-keyword-filtering.php' ),
|
35 |
-
'installed_inactive' => wprss_is_plugin_inactive( 'wp-rss-keyword-filtering/wp-rss-keyword-filtering.php' ),
|
36 |
-
'path' => 'wp-rss-keyword-filtering/wp-rss-keyword-filtering.php',
|
37 |
-
'url' => 'http://www.wprssaggregator.com/extension/keyword-filtering/'
|
38 |
-
);
|
39 |
-
$premium[] = array(
|
40 |
-
'title' => __( "Feed to Post", WPRSS_TEXT_DOMAIN ),
|
41 |
-
'description' => __( "Allows you to import feed items into posts or any other custom post type that you have created. Takes WP RSS Aggregator to a whole new level of flexibility.", WPRSS_TEXT_DOMAIN ),
|
42 |
-
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
43 |
-
'active' => is_plugin_active( 'wp-rss-feed-to-post/wp-rss-feed-to-post.php' ),
|
44 |
-
'installed_inactive' => wprss_is_plugin_inactive( 'wp-rss-feed-to-post/wp-rss-feed-to-post.php' ),
|
45 |
-
'path' => 'wp-rss-feed-to-post/wp-rss-feed-to-post.php',
|
46 |
-
'url' => 'http://www.wprssaggregator.com/extension/feed-to-post/'
|
47 |
-
);
|
48 |
-
$premium[] = array(
|
49 |
-
'title' => __( "Full Text RSS Feeds", WPRSS_TEXT_DOMAIN ),
|
50 |
-
'description' => __( "This add-ons provides the connectivity to our Full Text Premium service, which gives you unlimited feed items returned per feed source.", WPRSS_TEXT_DOMAIN ),
|
51 |
-
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
52 |
-
'active' => is_plugin_active( 'wp-rss-full-text-feeds/wp-rss-full-text.php' ),
|
53 |
-
'installed_inactive' => wprss_is_plugin_inactive( 'wp-rss-full-text-feeds/wp-rss-full-text.php' ),
|
54 |
-
'path' => 'wp-rss-full-text-feeds/wp-rss-full-text.php',
|
55 |
-
'url' => 'http://www.wprssaggregator.com/extension/full-text-rss-feeds/'
|
56 |
-
);
|
57 |
-
$premium[] = array(
|
58 |
-
'title' => __( "WordAi", WPRSS_TEXT_DOMAIN ),
|
59 |
-
'description' => __( "Allows you to spin the content for posts imported by Feed to Post using WordAi. Cleverly rewrite your posts without changing their meaning and maintaining human readability.", WPRSS_TEXT_DOMAIN ),
|
60 |
-
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
61 |
-
'active' => is_plugin_active( 'wp-rss-wordai/wp-rss-wordai.php' ),
|
62 |
-
'installed_inactive' => wprss_is_plugin_inactive( 'wp-rss-wordai/wp-rss-wordai.php' ),
|
63 |
-
'path' => 'wp-rss-wordai/wp-rss-wordai.php',
|
64 |
-
'url' => 'http://www.wprssaggregator.com/extension/wordai/'
|
65 |
-
);
|
66 |
-
$premium[] = array(
|
67 |
-
'title' => __( "Widget", WPRSS_TEXT_DOMAIN ),
|
68 |
-
'description' => __( "An add-on for WP RSS Aggregator that displays your imported feed items in a widget on your site. Intergrates well with Excerpts & Thumbnails", WPRSS_TEXT_DOMAIN ),
|
69 |
-
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
70 |
-
'active' => is_plugin_active( 'wp-rss-widget/wp-rss-widget.php' ),
|
71 |
-
'installed_inactive' => wprss_is_plugin_inactive( 'wp-rss-widget/wp-rss-widget.php' ),
|
72 |
-
'path' => 'wp-rss-widget/wp-rss-widget.php',
|
73 |
-
'url' => 'http://www.wprssaggregator.com/extension/widget/'
|
74 |
-
);
|
75 |
|
76 |
?>
|
77 |
<div class="wrap">
|
@@ -84,8 +21,10 @@
|
|
84 |
<div id="add-ons" class="clearfix">
|
85 |
|
86 |
<div class="add-on-group clearfix">
|
87 |
-
<?php foreach( $premium as $addon ): ?>
|
88 |
-
|
|
|
|
|
89 |
<!-- <a target="_blank" href="<?php echo $addon['url']; ?>">
|
90 |
<img src="<?php echo $addon['thumbnail']; ?>" />
|
91 |
</a> -->
|
@@ -94,10 +33,10 @@
|
|
94 |
<p><?php echo $addon['description']; ?></p>
|
95 |
</div>
|
96 |
<div class="footer">
|
97 |
-
<?php if( $
|
98 |
<a class="button button-disabled"><span class="wprss-sprite-tick"></span><?php _e( "Installed", WPRSS_TEXT_DOMAIN ); ?></a>
|
99 |
-
<?php elseif( $
|
100 |
-
<a class="button" href="<?php echo wp_nonce_url('plugins.php?action=activate&plugin='.$addon['
|
101 |
<?php else: ?>
|
102 |
<a target="_blank" href="<?php echo $addon['url']; ?>" class="button"><?php _e( "Purchase & Install", WPRSS_TEXT_DOMAIN ); ?></a>
|
103 |
<?php endif; ?>
|
@@ -113,6 +52,68 @@
|
|
113 |
<?php
|
114 |
|
115 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
/**
|
118 |
* Check if plugin file exists but plugin is inactive
|
8 |
*/
|
9 |
function wprss_addons_page_display() {
|
10 |
|
11 |
+
$premium = wprss_addons_get_extra();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
?>
|
14 |
<div class="wrap">
|
21 |
<div id="add-ons" class="clearfix">
|
22 |
|
23 |
<div class="add-on-group clearfix">
|
24 |
+
<?php foreach( $premium as $_code => $addon ): ?>
|
25 |
+
<?php $isActive = is_plugin_active($addon['basename']) ?>
|
26 |
+
<?php $isInstalledInactive = wprss_is_plugin_inactive($addon['basename']) ?>
|
27 |
+
<div class="add-on wp-box<?php if( $isActive ): ?> add-on-active<?php endif; ?> <?php echo sprintf('add-on-code-%1$s', $_code) ?>">
|
28 |
<!-- <a target="_blank" href="<?php echo $addon['url']; ?>">
|
29 |
<img src="<?php echo $addon['thumbnail']; ?>" />
|
30 |
</a> -->
|
33 |
<p><?php echo $addon['description']; ?></p>
|
34 |
</div>
|
35 |
<div class="footer">
|
36 |
+
<?php if( $isActive ): ?>
|
37 |
<a class="button button-disabled"><span class="wprss-sprite-tick"></span><?php _e( "Installed", WPRSS_TEXT_DOMAIN ); ?></a>
|
38 |
+
<?php elseif( $isInstalledInactive ): ?>
|
39 |
+
<a class="button" href="<?php echo wp_nonce_url('plugins.php?action=activate&plugin='.$addon['basename'], 'activate-plugin_'.$addon['basename'] ) ?>"><?php _e( "Activate", WPRSS_TEXT_DOMAIN ); ?></a>
|
40 |
<?php else: ?>
|
41 |
<a target="_blank" href="<?php echo $addon['url']; ?>" class="button"><?php _e( "Purchase & Install", WPRSS_TEXT_DOMAIN ); ?></a>
|
42 |
<?php endif; ?>
|
52 |
<?php
|
53 |
|
54 |
}
|
55 |
+
|
56 |
+
function wprss_addons_get_extra()
|
57 |
+
{
|
58 |
+
return apply_filters('wprss_extra_addons', array(
|
59 |
+
'et' => array(
|
60 |
+
'title' => 'Excerpts & Thumbnails',
|
61 |
+
'description' => __("Adds the ability to display thumbnails and excerpts. Perfect for adding some life and color to your feed item display. For more flexibility Feed to Post is a better option.", WPRSS_TEXT_DOMAIN),
|
62 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
63 |
+
'basename' => 'wp-rss-excerpts-thumbnails/wp-rss-excerpts-thumbnails.php',
|
64 |
+
'url' => 'http://www.wprssaggregator.com/extension/excerpts-thumbnails/'
|
65 |
+
),
|
66 |
+
'c' => array(
|
67 |
+
'title' => 'Categories',
|
68 |
+
'description' => __("Assign categories to your feed sources. Then display a particular category or multiple categories on a post or page via shortcodes.", WPRSS_TEXT_DOMAIN),
|
69 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
70 |
+
'basename' => 'wp-rss-categories/wp-rss-categories.php',
|
71 |
+
'url' => 'http://www.wprssaggregator.com/extension/categories/'
|
72 |
+
),
|
73 |
+
'kf' => array(
|
74 |
+
'title' => 'Keyword Filtering',
|
75 |
+
'description' => __("Import feeds that contain specific keywords in either the title or their content. Control what gets imported to your blog. You can use keywords, keyphrases and categories.", WPRSS_TEXT_DOMAIN),
|
76 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
77 |
+
'basename' => 'wp-rss-keyword-filtering/wp-rss-keyword-filtering.php',
|
78 |
+
'url' => 'http://www.wprssaggregator.com/extension/keyword-filtering/'
|
79 |
+
),
|
80 |
+
'ftp' => array(
|
81 |
+
'title' => 'Feed to Post',
|
82 |
+
'description' => __("Allows you to import feed items into posts or any other custom post type that you have created. Takes WP RSS Aggregator to a whole new level of flexibility.", WPRSS_TEXT_DOMAIN),
|
83 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
84 |
+
'basename' => 'wp-rss-feed-to-post/wp-rss-feed-to-post.php',
|
85 |
+
'url' => 'http://www.wprssaggregator.com/extension/feed-to-post/'
|
86 |
+
),
|
87 |
+
'ftr' => array(
|
88 |
+
'title' => 'Full Text RSS Feeds',
|
89 |
+
'description' => __("This add-ons provides the connectivity to our Full Text Premium service, which gives you unlimited feed items returned per feed source.", WPRSS_TEXT_DOMAIN),
|
90 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
91 |
+
'basename' => 'wp-rss-full-text-feeds/wp-rss-full-text.php',
|
92 |
+
'url' => 'http://www.wprssaggregator.com/extension/full-text-rss-feeds/'
|
93 |
+
),
|
94 |
+
'wai' => array(
|
95 |
+
'title' => 'WordAi',
|
96 |
+
'description' => __("Allows you to spin the content for posts imported by Feed to Post using WordAi. Cleverly rewrite your posts without changing their meaning and maintaining human readability.", WPRSS_TEXT_DOMAIN),
|
97 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
98 |
+
'basename' => 'wp-rss-wordai/wp-rss-wordai.php',
|
99 |
+
'url' => 'http://www.wprssaggregator.com/extension/wordai/'
|
100 |
+
),
|
101 |
+
'widget' => array(
|
102 |
+
'title' => 'Widget',
|
103 |
+
'description' => __("An add-on for WP RSS Aggregator that displays your imported feed items in a widget on your site. Intergrates well with Excerpts & Thumbnails", WPRSS_TEXT_DOMAIN),
|
104 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
105 |
+
'basename' => 'wp-rss-widget/wp-rss-widget.php',
|
106 |
+
'url' => 'http://www.wprssaggregator.com/extension/widget/'
|
107 |
+
),
|
108 |
+
'spc' => array(
|
109 |
+
'title' => 'SpinnerChief',
|
110 |
+
'description' => __("An extension for Feed to Post that allows you to integrate the SpinnerChief article spinner so that the imported content is both completely unique and completely readable.", WPRSS_TEXT_DOMAIN),
|
111 |
+
'thumbnail' => WPRSS_IMG . 'add-ons/wprss.jpg',
|
112 |
+
'basename' => 'wp-rss-spinnerchief/wp-rss-spinnerchief.php',
|
113 |
+
'url' => 'http://www.wprssaggregator.com/extension/spinnerchief/'
|
114 |
+
)
|
115 |
+
));
|
116 |
+
}
|
117 |
|
118 |
/**
|
119 |
* Check if plugin file exists but plugin is inactive
|
includes/admin-dashboard.php
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
'wprss-welcome',
|
29 |
'wprss_show_welcome_screen'
|
30 |
);
|
31 |
-
|
32 |
}
|
33 |
|
34 |
|
@@ -96,4 +96,32 @@
|
|
96 |
/*]]>*/
|
97 |
</style>
|
98 |
<?php
|
99 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
'wprss-welcome',
|
29 |
'wprss_show_welcome_screen'
|
30 |
);
|
31 |
+
|
32 |
}
|
33 |
|
34 |
|
96 |
/*]]>*/
|
97 |
</style>
|
98 |
<?php
|
99 |
+
}
|
100 |
+
|
101 |
+
add_filter( 'admin_footer_text', 'wprss_admin_footer' );
|
102 |
+
/**
|
103 |
+
* Adds footer text on the plugin pages.
|
104 |
+
*
|
105 |
+
* @param string $footer The footer text to filter
|
106 |
+
* @return string The filtered footer text with added plugin text, or the param
|
107 |
+
* value if the page is not specific to the plugin.
|
108 |
+
*/
|
109 |
+
function wprss_admin_footer( $footer ) {
|
110 |
+
// Current post type
|
111 |
+
global $typenow;
|
112 |
+
// Check if type is a plugin type. If not, stop
|
113 |
+
// Plugin type is in the form 'wprss_*'' where * is 'feed', 'blacklist', etc)
|
114 |
+
if ( stripos( $typenow, 'wprss_' ) !== 0 )
|
115 |
+
return $footer;
|
116 |
+
// Prepare fragments of the message
|
117 |
+
$thank_you = sprintf(
|
118 |
+
__( 'Thank you for using <a href="%1$s" target="_blank">WP RSS Aggregator</a>!', WPRSS_TEXT_DOMAIN ),
|
119 |
+
'http://www.wprssaggregator.com/'
|
120 |
+
);
|
121 |
+
$rate_us = sprintf(
|
122 |
+
__( 'Please <a href="%1$s" target="_blank">rate us</a>!', WPRSS_TEXT_DOMAIN ),
|
123 |
+
'https://wordpress.org/support/view/plugin-reviews/wp-rss-aggregator?filter=5#postform'
|
124 |
+
);
|
125 |
+
// Return the final text
|
126 |
+
return sprintf( '%1$s | <span class="wp-rss-footer-text">%2$s %3$s</span>', $footer, $thank_you, $rate_us );
|
127 |
+
}
|
includes/admin-help.php
CHANGED
@@ -57,28 +57,44 @@
|
|
57 |
* @since 4.7
|
58 |
*/
|
59 |
function wprss_premium_help_display() {
|
60 |
-
//
|
61 |
-
|
|
|
|
|
|
|
62 |
$statuses = get_option( 'wprss_settings_license_statuses', array() );
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
}
|
72 |
}
|
73 |
|
74 |
// If we didn't find an add-on with a valid license, show the free help text.
|
75 |
-
if ( $addon ===
|
76 |
wprss_free_help_display();
|
77 |
return;
|
78 |
}
|
79 |
|
80 |
// Get the full license info so we can prefill the name and email
|
81 |
-
$license = wprss_licensing_get_manager()->checkLicense( $addon, 'ALL' );
|
82 |
$customer_name = is_object($license) ? $license->customer_name : '';
|
83 |
$customer_email = is_object($license) ? $license->customer_email : '';
|
84 |
|
57 |
* @since 4.7
|
58 |
*/
|
59 |
function wprss_premium_help_display() {
|
60 |
+
// Addon and license object, both detected in the below algorithm that searches for a
|
61 |
+
// premium addon that is activated with a valid license
|
62 |
+
$addon = null;
|
63 |
+
$license = null;
|
64 |
+
// Get license statuses option
|
65 |
$statuses = get_option( 'wprss_settings_license_statuses', array() );
|
66 |
+
// Iterate all statuses
|
67 |
+
foreach ( $statuses as $_key => $_value ) {
|
68 |
+
// If not a license status key, continue to next
|
69 |
+
$_keyPos = strpos($_key, '_license_status');
|
70 |
+
if ( $_keyPos === FALSE ) {
|
71 |
+
continue;
|
72 |
+
}
|
73 |
+
// If the status is not valid, contine to next
|
74 |
+
if ($_value !== 'valid') {
|
75 |
+
continue;
|
76 |
+
}
|
77 |
+
// Get the addon ID
|
78 |
+
$_addonId = substr( $_key, 0, $_keyPos );
|
79 |
+
// Get the license
|
80 |
+
$_license = wprss_licensing_get_manager()->checkLicense( $_addonId, 'ALL' );
|
81 |
+
// If the license is not null
|
82 |
+
if ($_license !== null) {
|
83 |
+
// Save its details
|
84 |
+
$addon = $_addonId;
|
85 |
+
$license = $_license;
|
86 |
+
// And stop iterating
|
87 |
+
break;
|
88 |
}
|
89 |
}
|
90 |
|
91 |
// If we didn't find an add-on with a valid license, show the free help text.
|
92 |
+
if ( $addon === null || $license === null ) {
|
93 |
wprss_free_help_display();
|
94 |
return;
|
95 |
}
|
96 |
|
97 |
// Get the full license info so we can prefill the name and email
|
|
|
98 |
$customer_name = is_object($license) ? $license->customer_name : '';
|
99 |
$customer_email = is_object($license) ? $license->customer_email : '';
|
100 |
|
includes/functions.php
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Helper and misc functions.
|
4 |
+
*
|
5 |
+
* @todo Make this part of Core instead
|
6 |
+
*/
|
7 |
+
|
8 |
+
if (!function_exists('wprss_get_namespace')) {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Get the namespace of a class
|
12 |
+
*
|
13 |
+
* @since 1.0
|
14 |
+
* @param string|object|null $class The class name or instance, for which to get the namespace.
|
15 |
+
* @param int|null $depth The depth of the namespace to retrieve.
|
16 |
+
* If omitted, the whole namespace will be retrieved.
|
17 |
+
* @param bool $asString If true, the result will be a string; otherwise, array with namespace parts.
|
18 |
+
* @return array|string The namespace of the class.
|
19 |
+
*/
|
20 |
+
function wprss_get_namespace($class, $depth = null, $asString = false)
|
21 |
+
{
|
22 |
+
$ns = '\\';
|
23 |
+
|
24 |
+
// Can accept an instance
|
25 |
+
if (is_object($class)) {
|
26 |
+
$class = get_class($class);
|
27 |
+
}
|
28 |
+
|
29 |
+
$namespace = explode($ns, (string) $class);
|
30 |
+
|
31 |
+
// This was a root class name, no namespace
|
32 |
+
array_pop($namespace);
|
33 |
+
if (!count($namespace)) {
|
34 |
+
return null;
|
35 |
+
}
|
36 |
+
|
37 |
+
$namespace = array_slice($namespace, 0, $depth);
|
38 |
+
|
39 |
+
return $asString ? implode($ns, $namespace) : $namespace;
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
if (!function_exists('wprss_is_root_namespace')) {
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Check if a namespace is a root namespace.
|
47 |
+
*
|
48 |
+
* @since 1.0
|
49 |
+
* @param string $namespace The namespace to check.
|
50 |
+
* @param bool $checkClass If true, and a class or interface with the name of the specified namespace exists,
|
51 |
+
* will make this function return true. Otherwise, the result depends purely on the namespace string.
|
52 |
+
* @return boolean True if the namespace is a root namespace; false otherwise.
|
53 |
+
*/
|
54 |
+
function wprss_is_root_namespace($namespace, $checkClass = true) {
|
55 |
+
$isRoot = substr($namespace, 0, 1) === '\\';
|
56 |
+
return $checkClass
|
57 |
+
? $isRoot || class_exists($namespace)
|
58 |
+
: $isRoot;
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
if (!function_exists('string_had_prefix')) {
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Check for and possibly remove a prefix from a string.
|
66 |
+
*
|
67 |
+
* @since 1.0
|
68 |
+
* @param string $string The string to check and normalize.
|
69 |
+
* @param string $prefix The prefix to check for.
|
70 |
+
* @return string Checks if a string starts with the specified prefix.
|
71 |
+
* If yes, removes it and returns true; otherwise, false;
|
72 |
+
*/
|
73 |
+
function string_had_prefix(&$string, $prefix)
|
74 |
+
{
|
75 |
+
$prefixLength = strlen($prefix);
|
76 |
+
if (substr($string, 0, $prefixLength) === $prefix) {
|
77 |
+
$string = substr($string, $prefixLength);
|
78 |
+
return true;
|
79 |
+
}
|
80 |
+
|
81 |
+
return false;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
if (!function_exists('uri_is_absolute')) {
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Check if the URI is absolute.
|
89 |
+
*
|
90 |
+
* Check is made based on whether or not there's a '//' sequence
|
91 |
+
* somewhere in the beginning.
|
92 |
+
*
|
93 |
+
* @since 1.0
|
94 |
+
* @param string $uri The URI to check.
|
95 |
+
* @return boolean True of the given string contains '//' within the first 10 chars;
|
96 |
+
* otherwise, false.
|
97 |
+
*/
|
98 |
+
function uri_is_absolute($uri)
|
99 |
+
{
|
100 |
+
$beginning = substr($uri, 0, 10);
|
101 |
+
return strpos($beginning, '//') !== false;
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
if ( ! function_exists('array_merge_recursive_distinct') ) {
|
106 |
+
/**
|
107 |
+
* array_merge_recursive does indeed merge arrays, but it converts values with duplicate
|
108 |
+
* keys to arrays rather than overwriting the value in the first array with the duplicate
|
109 |
+
* value in the second array, as array_merge does. I.e., with array_merge_recursive,
|
110 |
+
* this happens (documented behavior):
|
111 |
+
*
|
112 |
+
* array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
|
113 |
+
* => array('key' => array('org value', 'new value'));
|
114 |
+
*
|
115 |
+
* array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
|
116 |
+
* Matching keys' values in the second array overwrite those in the first array, as is the
|
117 |
+
* case with array_merge, i.e.:
|
118 |
+
*
|
119 |
+
* array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
|
120 |
+
* => array('key' => array('new value'));
|
121 |
+
*
|
122 |
+
* Parameters are passed by reference, though only for performance reasons. They're not
|
123 |
+
* altered by this function.
|
124 |
+
*
|
125 |
+
* @since 1.0
|
126 |
+
* @param array $array1
|
127 |
+
* @param array $array2
|
128 |
+
* @return array
|
129 |
+
* @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
|
130 |
+
* @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
|
131 |
+
*/
|
132 |
+
function array_merge_recursive_distinct ( array &$array1, array &$array2 ) {
|
133 |
+
$merged = $array1;
|
134 |
+
foreach ( $array2 as $key => &$value ) {
|
135 |
+
if ( is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) ) {
|
136 |
+
$merged [$key] = array_merge_recursive_distinct ( $merged [$key], $value );
|
137 |
+
}
|
138 |
+
else $merged [$key] = $value;
|
139 |
+
}
|
140 |
+
return $merged;
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
+
if (!function_exists('array_pick')) {
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Picks values with certain keys from an array.
|
148 |
+
*
|
149 |
+
* @since 1.0
|
150 |
+
* @param array $array An array, from which to pick. Will not be modified; passed by refrence for efficiency.
|
151 |
+
* @param string|int|array $keys A key or array of keys to pick.
|
152 |
+
* @return array
|
153 |
+
*/
|
154 |
+
function array_pick($array, $keys)
|
155 |
+
{
|
156 |
+
$keys = (array)$keys;
|
157 |
+
return array_intersect_key($array, array_flip($keys));
|
158 |
+
}
|
159 |
+
}
|
includes/image-caching.php
CHANGED
@@ -481,7 +481,7 @@ class WPRSS_Image_Cache {
|
|
481 |
if ( !is_null( $target_path ) )
|
482 |
$path = $target_path;
|
483 |
|
484 |
-
if ( is_null( $request_timeout ) )
|
485 |
$timeout = $request_timeout;
|
486 |
|
487 |
// Absolute path to the cache file
|
481 |
if ( !is_null( $target_path ) )
|
482 |
$path = $target_path;
|
483 |
|
484 |
+
if ( !is_null( $request_timeout ) )
|
485 |
$timeout = $request_timeout;
|
486 |
|
487 |
// Absolute path to the cache file
|
includes/system-info.php
CHANGED
@@ -30,7 +30,10 @@
|
|
30 |
</textarea>
|
31 |
<p class="submit">
|
32 |
<input type="hidden" name="wprss-action" value="download_sysinfo" />
|
33 |
-
|
|
|
|
|
|
|
34 |
</p>
|
35 |
</form>
|
36 |
|
30 |
</textarea>
|
31 |
<p class="submit">
|
32 |
<input type="hidden" name="wprss-action" value="download_sysinfo" />
|
33 |
+
<button type="submit" class="button button-primary" id="wprss-download-sysinfo">
|
34 |
+
<i class="fa fa-download"></i>
|
35 |
+
<?php _e( 'Download System Info File', WPRSS_TEXT_DOMAIN ) ?>
|
36 |
+
</button>
|
37 |
</p>
|
38 |
</form>
|
39 |
|
readme.txt
CHANGED
@@ -3,79 +3,79 @@ Contributors: jeangalea, Mekku, xedin.unknown, markzahra, doytch, chiragswadia
|
|
3 |
Plugin URI: http://www.wprssaggregator.com
|
4 |
Tags: rss, aggregation, autoblog, autoblog aggregator, autoblogger, autoblogging, autopost, content curation, feed aggregation, feed aggregator, feed import, feed reader, feed to post, feeds, multi feed import, multi feed importer, multi rss feeds, multiple feed import, multiple rss feeds,rss aggregator, rss feader, RSS Feed, rss feed to post, rss feeder, RSS import, rss multi importer, rss post importer, rss retriever, rss to post, syndication
|
5 |
Requires at least: 4.0
|
6 |
-
Tested up to: 4.4
|
7 |
-
Stable tag: 4.8
|
8 |
License: GPLv2 or later
|
9 |
-
|
10 |
|
11 |
|
12 |
== Description ==
|
13 |
|
14 |
-
WP RSS Aggregator is the most comprehensive and elegant RSS feed solution for WordPress.
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
With WP RSS Aggregator, you can:
|
19 |
-
|
20 |
-
* Display feeds from one or more sites on your blog
|
21 |
-
* Aggregate feeds from multiple sites
|
22 |
-
|
23 |
-
You can add any number of feeds through an administration panel, the plugin will then pull feed items from these sites, merge them and display them in date order.
|
24 |
-
|
25 |
-
To [display your imported feed items](http://wordpress.org/plugins/wp-rss-aggregator/screenshots/), you can use a shortcode or call the display function directly from within your theme.
|
26 |
|
27 |
= Highlighted Features =
|
28 |
|
29 |
-
*
|
30 |
-
*
|
31 |
-
*
|
32 |
-
*
|
33 |
-
*
|
34 |
-
*
|
35 |
-
*
|
36 |
-
*
|
37 |
-
*
|
38 |
-
* Set the
|
39 |
-
*
|
40 |
-
*
|
41 |
-
*
|
42 |
-
*
|
43 |
-
* Extendable via action and filter hooks
|
44 |
-
*
|
|
|
45 |
|
46 |
= Premium Add-Ons =
|
47 |
-
|
48 |
|
49 |
-
* [Feed to Post](http://www.wprssaggregator.com/
|
50 |
-
* [Keyword Filtering](http://www.wprssaggregator.com/
|
51 |
-
* [Excerpts & Thumbnails](http://www.wprssaggregator.com/
|
52 |
-
* [Categories](http://www.wprssaggregator.com/
|
53 |
-
* [
|
54 |
-
* [
|
|
|
|
|
55 |
|
56 |
-
|
|
|
|
|
|
|
|
|
57 |
|
58 |
= Demo =
|
59 |
-
The core plugin can be seen in use on
|
60 |
|
61 |
= Video Walkthrough =
|
|
|
62 |
[youtube http://www.youtube.com/watch?v=fcENPsmJbvc]
|
63 |
|
64 |
= Documentation =
|
65 |
-
|
66 |
|
67 |
= As featured on =
|
68 |
-
* [
|
69 |
-
* [
|
70 |
-
* [
|
71 |
-
* [
|
72 |
-
* [
|
73 |
-
* [
|
|
|
74 |
* [Kikolani](http://kikolani.com/create-latest-posts-portfolio-page-wp-rss-aggregator.html)
|
75 |
-
* [ManageWP
|
76 |
-
* [
|
77 |
-
* [
|
78 |
-
* [IndexWP](www.indexwp.com/wp-rss-aggregator-plugin-review/)
|
79 |
* [WPulsar](http://www.wpulsar.com/wp-rss-aggregator-plugin-feed-to-posts-keyword-filtering-review/)
|
80 |
* [Kevin Muldoon](http://www.kevinmuldoon.com/wp-rss-aggregator-wordpress-plugin/)
|
81 |
|
@@ -87,31 +87,24 @@ Instructions for plugin usage are available on the plugin's [documentation page]
|
|
87 |
|
88 |
== Installation ==
|
89 |
|
90 |
-
1. Upload the `wp-rss-aggregator` folder to the `/wp-content/plugins/` directory
|
91 |
-
2. Activate the WP RSS Aggregator plugin
|
92 |
3. Configure the plugin by going to the `RSS Aggregator` menu item that appears in your dashboard menu.
|
93 |
-
|
|
|
|
|
94 |
|
95 |
-
|
96 |
|
97 |
-
|
98 |
-
* links_after
|
99 |
-
* link_before
|
100 |
-
* link_after
|
101 |
-
* limit
|
102 |
-
* source
|
103 |
-
* exclude
|
104 |
-
* pagination
|
105 |
|
106 |
-
An example of a shortcode with parameters:
|
107 |
`[wp_rss_aggregator link_before='<li class="feed-link">' link_after='</li>']`
|
108 |
-
It is advisable to use the 'HTML' view of the editor when inserting the shortcode with paramters.
|
109 |
|
110 |
-
|
111 |
|
112 |
__Usage within theme files__
|
113 |
|
114 |
-
|
115 |
`
|
116 |
<?php
|
117 |
wprss_display_feed_items( $args = array(
|
@@ -153,7 +146,7 @@ No, our plugin does not currently import from JSON, it only imports from RSS and
|
|
153 |
|
154 |
= Why do I get “No feed items found” when I insert the shortcode on a page or post? =
|
155 |
|
156 |
-
Try adding a few more feed sources and make sure they are valid by using the RSS Feed
|
157 |
|
158 |
Secondly make sure your WordPress cron system is working well. If not, the feeds cannot be imported. If in doubt you can go to RSS Aggregator > Debugging and hit the red button to re-import all feed items. If the problem persists contact support.
|
159 |
|
@@ -169,11 +162,11 @@ Yes, along with the [Feed to Post](http://www.wprssaggregator.com/extensions/fee
|
|
169 |
|
170 |
Sure! We wrote a [post](http://www.wprssaggregator.com/add-ons-purchase/) just for you. Read about which add-ons you should buy, we explain the different types of usage so you’ll know what to expect when purchasing.
|
171 |
|
172 |
-
If you need any further help you can contact our support team
|
173 |
|
174 |
= Where can I find the documentation for the plugin? =
|
175 |
|
176 |
-
|
177 |
|
178 |
|
179 |
== Screenshots ==
|
@@ -193,6 +186,13 @@ The full documentation section can be found on the [WP RSS Aggregator website](h
|
|
193 |
|
194 |
== Changelog ==
|
195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
= 4.8 (2015-12-30) =
|
197 |
* Fixed bug: Licensing notices will now be displayed again.
|
198 |
* Enhanced: Major licensing system improvements.
|
@@ -709,708 +709,5 @@ Fixed bug: Broken links in the "Add-ons" page, to add-on pages on our site.
|
|
709 |
* Code refactoring
|
710 |
* Changes in file and folder structure
|
711 |
|
712 |
-
= Version 1.0 (2012-01-06) =
|
713 |
-
=== WP RSS Aggregator ===
|
714 |
-
Contributors: jeangalea, Mekku, xedin.unknown, markzahra, doytch, chiragswadia
|
715 |
-
Plugin URI: http://www.wprssaggregator.com
|
716 |
-
Tags: rss, aggregation, autoblog, autoblog aggregator, autoblogger, autoblogging, autopost, content curation, feed aggregation, feed aggregator, feed import, feed reader, feed to post, feeds, multi feed import, multi feed importer, multi rss feeds, multiple feed import, multiple rss feeds,rss aggregator, rss feader, RSS Feed, rss feed to post, rss feeder, RSS import, rss multi importer, rss post importer, rss retriever, rss to post, syndication
|
717 |
-
Requires at least: 4.0
|
718 |
-
Tested up to: 4.3.1
|
719 |
-
Stable tag: 4.7.7
|
720 |
-
License: GPLv2 or later
|
721 |
-
The no.1 RSS feed importer for WordPress. Premium add-ons available for more functionality.
|
722 |
-
|
723 |
-
|
724 |
-
== Description ==
|
725 |
-
|
726 |
-
WP RSS Aggregator is the most comprehensive and elegant RSS feed solution for WordPress.
|
727 |
-
|
728 |
-
The original and premier plugin for importing, merging and displaying RSS and Atom feeds on your WordPress site.
|
729 |
-
|
730 |
-
With WP RSS Aggregator, you can:
|
731 |
-
|
732 |
-
* Display feeds from one or more sites on your blog
|
733 |
-
* Aggregate feeds from multiple sites
|
734 |
-
|
735 |
-
You can add any number of feeds through an administration panel, the plugin will then pull feed items from these sites, merge them and display them in date order.
|
736 |
-
|
737 |
-
To [display your imported feed items](http://wordpress.org/plugins/wp-rss-aggregator/screenshots/), you can use a shortcode or call the display function directly from within your theme.
|
738 |
-
|
739 |
-
= Highlighted Features =
|
740 |
-
|
741 |
-
* Export a custom RSS feed based on your feed sources
|
742 |
-
* Pagination
|
743 |
-
* Set the feed import time interval
|
744 |
-
* Scheduling of feed imports by feed source
|
745 |
-
* Various shortcode parameters you can use to further customize the output
|
746 |
-
* Choose whether to show/hide sources and dates
|
747 |
-
* Choose the date format
|
748 |
-
* Set the links as no-follow or not, or add no follow to meta tag
|
749 |
-
* Select how you would like the links to open (in a Lightbox, a new window, or the current window)
|
750 |
-
* Set the name of the feed source
|
751 |
-
* Select number of posts per feed you want to show and store
|
752 |
-
* Opens YouTube, DailyMotion and Vimeo videos directly
|
753 |
-
* Limit number of feed items stored in the database
|
754 |
-
* Feed autodiscovery, which lets you add feeds without even knowing the exact URL.
|
755 |
-
* Extendable via action and filter hooks
|
756 |
-
* Integrated with the Simplepie library that come with WordPress. This includes RSS 0.91 and RSS 1.0 formats, the popular RSS 2.0 format, Atom etc.
|
757 |
-
|
758 |
-
= Premium Add-Ons =
|
759 |
-
Add-Ons that add more functionality to the core plugin are [available for purchase](http://www.wprssaggregator.com/extensions/).
|
760 |
-
|
761 |
-
* [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) - an advanced importer that lets you import RSS to posts or custom post types. Populate a website in minutes (autoblog). This is the most popular extension.
|
762 |
-
* [Keyword Filtering](http://www.wprssaggregator.com/extensions/keyword-filtering) - filter imported feeds based on keywords, so you only get items you're interested in.
|
763 |
-
* [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) - display excerpts and thumbnails together with the title, date and source.
|
764 |
-
* [Categories](http://www.wprssaggregator.com/extensions/categories) - categorise your feed sources and display items from a particular category at will within your site.
|
765 |
-
* [WordAi](http://www.wprssaggregator.com/extension/wordai/) - WordAi allows users to take an RSS feed and turn it into new content that is both completely unique and completely readable.
|
766 |
-
* [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) - connectivity to our Full Text Premium service, which gives you unlimited feed items returned per feed source.
|
767 |
-
* [Widget](http://www.wprssaggregator.com/extension/widget/) - Add a widget that displays imported feed items.
|
768 |
-
|
769 |
-
We also provide a [Feed Creator](http://createfeed.wprssaggregator.com) service, that allows you to generate RSS feeds from any webpage, even if it doesn't have its own RSS feed.
|
770 |
-
|
771 |
-
= Demo =
|
772 |
-
The core plugin can be seen in use on the [demo page](http://www.wprssaggregator.com/demo/).
|
773 |
-
|
774 |
-
= Video Walkthrough =
|
775 |
-
[youtube http://www.youtube.com/watch?v=fcENPsmJbvc]
|
776 |
-
|
777 |
-
= Documentation =
|
778 |
-
Instructions for plugin usage are available on the plugin's [documentation page](http://www.wprssaggregator.com/documentation/).
|
779 |
-
|
780 |
-
= As featured on =
|
781 |
-
* [Latest WP](http://www.latestwp.com/2015/03/15/wp-rss-aggregator-plugin-review/)
|
782 |
-
* [WP Beginner](http://www.wpbeginner.com/plugins/how-to-fetch-feeds-in-wordpress-using-wp-rss-aggregator/)
|
783 |
-
* [WPEXplorer](http://www.wpexplorer.com/custom-rss-aggregator-plugin/)
|
784 |
-
* [WP Kube](http://www.wpkube.com/wp-rss-aggregator-wordpress-review/)
|
785 |
-
* [Torquemag](http://torquemag.io/wp-rss-aggregator-review-do-more-with-rss-feeds/)
|
786 |
-
* [MyWPExpert](http://www.mywpexpert.com/wordpress-rss-aggregator-plugin)
|
787 |
-
* [Kikolani](http://kikolani.com/create-latest-posts-portfolio-page-wp-rss-aggregator.html)
|
788 |
-
* [ManageWP Plugins of the Month](http://managewp.com/free-wordpress-plugins-march-2014)
|
789 |
-
* [TidyRepo](http://tidyrepo.com/wp-rss-aggregator/)
|
790 |
-
* [WP Eka](http://www.wpeka.com/wp-rss-aggregators-plugin.html)
|
791 |
-
* [IndexWP](www.indexwp.com/wp-rss-aggregator-plugin-review/)
|
792 |
-
* [WPulsar](http://www.wpulsar.com/wp-rss-aggregator-plugin-feed-to-posts-keyword-filtering-review/)
|
793 |
-
* [Kevin Muldoon](http://www.kevinmuldoon.com/wp-rss-aggregator-wordpress-plugin/)
|
794 |
-
|
795 |
-
= Translations =
|
796 |
-
* Italian - Davide De Maestri
|
797 |
-
* Spanish - Andrew Kurtis
|
798 |
-
* Brazilian Portugese - Bruno Calheira
|
799 |
-
* Dutch - Erick Suiker
|
800 |
-
|
801 |
-
== Installation ==
|
802 |
-
|
803 |
-
1. Upload the `wp-rss-aggregator` folder to the `/wp-content/plugins/` directory
|
804 |
-
2. Activate the WP RSS Aggregator plugin through the 'Plugins' menu in WordPress
|
805 |
-
3. Configure the plugin by going to the `RSS Aggregator` menu item that appears in your dashboard menu.
|
806 |
-
3. Use the shortcode in your posts or pages: `[wp-rss-aggregator]`
|
807 |
-
|
808 |
-
The parameters accepted are:
|
809 |
-
|
810 |
-
* links_before
|
811 |
-
* links_after
|
812 |
-
* link_before
|
813 |
-
* link_after
|
814 |
-
* limit
|
815 |
-
* source
|
816 |
-
* exclude
|
817 |
-
* pagination
|
818 |
-
|
819 |
-
An example of a shortcode with parameters:
|
820 |
-
`[wp_rss_aggregator link_before='<li class="feed-link">' link_after='</li>']`
|
821 |
-
It is advisable to use the 'HTML' view of the editor when inserting the shortcode with paramters.
|
822 |
-
|
823 |
-
For a full list of shortcode parameters and usage guide please refer to the [documentation](http://www.wprssaggregator.com/docs/shortcodes/).
|
824 |
-
|
825 |
-
__Usage within theme files__
|
826 |
-
|
827 |
-
An example of a function call from within the theme's files:
|
828 |
-
`
|
829 |
-
<?php
|
830 |
-
wprss_display_feed_items( $args = array(
|
831 |
-
'links_before' => '<ul>',
|
832 |
-
'links_after' => '</ul>',
|
833 |
-
'link_before' => '<li>',
|
834 |
-
'link_after' => '</li>',
|
835 |
-
'limit' => '8',
|
836 |
-
'source' => '5,9'
|
837 |
-
));
|
838 |
-
?>
|
839 |
-
`
|
840 |
-
|
841 |
-
OR
|
842 |
-
|
843 |
-
`<?php do_shortcode('[wp-rss-aggregator]'); ?>`
|
844 |
-
|
845 |
-
|
846 |
-
== Frequently Asked Questions ==
|
847 |
-
= How do I display the imported feed items? =
|
848 |
-
|
849 |
-
You can either use the shortcode in your posts and pages:
|
850 |
-
`[wp-rss-aggregator]`
|
851 |
-
|
852 |
-
or you can call the function directly within your theme:
|
853 |
-
`<?php wprss_display_feed_items(); ?>`
|
854 |
-
|
855 |
-
= Is there a limit on the number of feed sources I can use? =
|
856 |
-
|
857 |
-
There is no limit in place for the number of feed sources. Having many (50+) feed sources should not present any problems in itself.
|
858 |
-
|
859 |
-
However, pulling in posts from many sites is bound to put your server under some stress, so you might want to consider using a hosting solution that goes beyond your typical shared host.
|
860 |
-
|
861 |
-
Check out our dedicated page for hosting recommendations.
|
862 |
-
|
863 |
-
= Does WP RSS Aggregator work using JSON as the source? =
|
864 |
-
|
865 |
-
No, our plugin does not currently import from JSON, it only imports from RSS and Atom structured XML.
|
866 |
-
|
867 |
-
= Why do I get “No feed items found” when I insert the shortcode on a page or post? =
|
868 |
-
|
869 |
-
Try adding a few more feed sources and make sure they are valid by using the RSS Feed validator.
|
870 |
-
|
871 |
-
Secondly make sure your WordPress cron system is working well. If not, the feeds cannot be imported. If in doubt you can go to RSS Aggregator > Debugging and hit the red button to re-import all feed items. If the problem persists contact support.
|
872 |
-
|
873 |
-
= Can I store imported feed items as posts? =
|
874 |
-
|
875 |
-
Yes! You can do that with the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) add-on. You will not only be able to store items as posts, but also as other custom post types, as well as set the author, auto set tags and categories, import images into the gallery or set featured images, and much more.
|
876 |
-
|
877 |
-
= Some RSS feeds only give a short excerpt. Any way around that? =
|
878 |
-
|
879 |
-
Yes, along with the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) add-on we have another add-on called [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) that can get the full content of those feeds that only supply a short excerpt.
|
880 |
-
|
881 |
-
= I’m not sure which premium add-ons are right for me. Can you help me out? =
|
882 |
-
|
883 |
-
Sure! We wrote a post just for you. Read about which add-ons you should buy, we explain the different types of usage so you’ll know what to expect when purchasing.
|
884 |
-
|
885 |
-
If you need any further help you can contact our support team [here](http://www.wprssaggregator.com/contact/).
|
886 |
-
|
887 |
-
= Where can I find the documentation for the plugin? =
|
888 |
-
|
889 |
-
The full documentation section can be found on the [WP RSS Aggregator website](www.wprssaggregator.com/documentation/), the documentation also includes an extensive FAQ list.
|
890 |
-
|
891 |
-
|
892 |
-
== Screenshots ==
|
893 |
-
|
894 |
-
1. Feed items imported by WP RSS Aggregator displayed on the front-end using the shortcode.
|
895 |
-
|
896 |
-
2. Feed Items imported by WP RSS Aggregator and displayed with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) add-on installed.
|
897 |
-
|
898 |
-
3. Adding/Editing a feed source.
|
899 |
-
|
900 |
-
4. The feed sources.
|
901 |
-
|
902 |
-
5. The imported feeds items.
|
903 |
-
|
904 |
-
6. WP RSS Aggregator's Settings page.
|
905 |
-
|
906 |
-
|
907 |
-
== Changelog ==
|
908 |
-
|
909 |
-
= 4.7.7 (2015-10-19) =
|
910 |
-
* Enhanced: Optimized checking for plugin updates.
|
911 |
-
|
912 |
-
= 4.7.6 (2015-10-07) =
|
913 |
-
* Enhanced: Feeds that fail to validate due to whitespace at the beginning are now supported by the plugin.
|
914 |
-
* Fixed bug: Undefined variables in the System Info section in the Debugging page.
|
915 |
-
* Fixed bug: Add-on license expiration notices could not be dismissed.
|
916 |
-
|
917 |
-
= 4.7.5 (2015-09-02) =
|
918 |
-
* Usage tracking now disabled.
|
919 |
-
* Fixed bug: error related to undefined `ajaxurl` JS variable gone from frontend.
|
920 |
-
* Enhanced: Licensing errors will be output to debug log.
|
921 |
-
* Enhanced: Improved compatibility with plugins that allow AJAX searching in the backend.
|
922 |
-
|
923 |
-
= 4.7.4 (2015-08-20) =
|
924 |
-
* Requirement: WordPress 4.0 or greater now required.
|
925 |
-
* Fixed bug in image caching
|
926 |
-
* Fixed bug in admin interface due to incorrectly translated IDs
|
927 |
-
|
928 |
-
= 4.7.3 (2015-08-04) =
|
929 |
-
* Enhanced: Core now implements an image cache logic.
|
930 |
-
* Enhanced: Add-ons on the "Add-ons" page now have an installed-but-inactive status.
|
931 |
-
* Enhanced: Google Alerts permalinks will now be normalized.
|
932 |
-
* Enhanced: Russian translation added.
|
933 |
-
* Fixed bug: Inline help (tooltips) translations now work.
|
934 |
-
* Fixed bug: Link to the Feed to Post add-on on the welcome page is no longer broken.
|
935 |
-
|
936 |
-
= 4.7.2 (2015-06-30) =
|
937 |
-
* Enhanced: Copyright updated.
|
938 |
-
* Fixed bug: Word trimming no longer adds extra closing tags at the end.
|
939 |
-
* Fixed bug: Presence of `idna_convert` class no longer causes infinite redirects on some servers.
|
940 |
-
* Fixed bug: Warning of unterminated comment no longer thrown in PHP 5.5.
|
941 |
-
* Fixed bug: Added default value for "Unique Titles" option.
|
942 |
-
* Fixed bug: Having a the port number specified with the database host no longer causes issues with the `mysqli` adapter in System Info on some servers.
|
943 |
-
* Fixed bug: Nested options of inline help controller no longer cause a fatal error.
|
944 |
-
* Fixed bug: Notices will no longer be displayed during rendering of feed items due to absence of required default values.
|
945 |
-
|
946 |
-
= 4.7.1 (2015-04-23) =
|
947 |
-
* Fixed bug: No warning will be thrown when fetching feeds.
|
948 |
-
|
949 |
-
= 4.7 (2015-04-21) =
|
950 |
-
* New: Optionally import only items with titles that don't already exist.
|
951 |
-
* Enhanced: Accessing feeds over HTTPS is now possible.
|
952 |
-
* Enhanced: Added support for multibyte strings in some places.
|
953 |
-
* Enhanced: Increased JS compatibility with other plugins.
|
954 |
-
* Enhanced: Increased UI support for mobile devices.
|
955 |
-
* Fixed bug: Having no mysqli extension no longer causes an error to appear in the debug info.
|
956 |
-
* Fixed bug: Saving an empty license key no longer results in a warning.
|
957 |
-
|
958 |
-
= 4.6.13 (2015-03-20) =
|
959 |
-
* Fixed bug: The "Force feed" option wasn't being correctly used.
|
960 |
-
|
961 |
-
= 4.6.12 (2015-03-09) =
|
962 |
-
* Fixed bug: The "Force feed" option was being removed by the Feed to Post add-on.
|
963 |
-
|
964 |
-
= 4.6.11 (2015-03-04) =
|
965 |
-
* Enhanced: The Help page now includes a support form if a premium add-on is detected.
|
966 |
-
* Enhanced: Updated some translations for admin options.
|
967 |
-
* Fixed bug: Help tooltips are now optimized for iPad screens.
|
968 |
-
* Fixed bug: Errors on the licensing page when a license code has not yet been entered.
|
969 |
-
|
970 |
-
= 4.6.10 (2015-02-10) =
|
971 |
-
* Enhanced: AJAX license activation.
|
972 |
-
* Enhanced: License form more reliable.
|
973 |
-
* Enhanced: license-related UI improvements
|
974 |
-
* New: Markdown library added. Changelog now read from readme.
|
975 |
-
* Fixed bug: Saving license keys not longer triggers error in some cases.
|
976 |
-
|
977 |
-
= 4.6.9 (2015-01-21) =
|
978 |
-
* Enhanced: Admin user will now be warned about invalid or expiring licenses.
|
979 |
-
* Enhanced: Admin notices logic centralized in this plugin.
|
980 |
-
* Fixed: Multiple small-scale security vulnerabilities.
|
981 |
-
* Fixed: Ampersand in feed URL no longer causes the product of generated feeds to be invalidated by W3C Validator.
|
982 |
-
|
983 |
-
= 4.6.8 (2015-01-07) =
|
984 |
-
* Enhanced: Added more logging during feed importing.
|
985 |
-
* Enhanced: Irrelevent metaboxes added by other plugins are now removed from the Add/Edit Feed Source page.
|
986 |
-
* Fixed bug: Valid feed URLS were being invalidated.
|
987 |
-
* Fixed bug: The Blacklist feature was being hidden when the Feed to Post add-on was enabled.
|
988 |
-
* Fixed bug: Patched a vulnerability where any user on the site can issue a feed fetch.
|
989 |
-
* Fixed bug: The "Activate" and "Pause" actions are not shown in the bulk actions dropdown in WordPress v4.1.
|
990 |
-
|
991 |
-
= 4.6.7 (2014-12-17) =
|
992 |
-
* Enhanced: Some minor interface updates.
|
993 |
-
* Enhanced: Added filters for use by the premium add-ons.
|
994 |
-
|
995 |
-
= 4.6.6 (2014-12-06) =
|
996 |
-
* Enhanced: Added output layouts for feed sources and feed items.
|
997 |
-
* Enhanced: Updated EDD updater class to version 1.5.
|
998 |
-
* Enhanced: Added time limit extending to prevent script from exhausting its execution time limit while importing.
|
999 |
-
* Fixed bug: The "Delete and Re-import" button was deleting items but not re-importing.
|
1000 |
-
* Fixed bug: Non-object errors when a feed source is deleted while importing.
|
1001 |
-
|
1002 |
-
= 4.6.5 (2014-11-17) =
|
1003 |
-
* Enhanced: Improved the logging.
|
1004 |
-
* Enhanced: Improved the licensing fields.
|
1005 |
-
* Enhanced: Updated the EDD updater class to the latest version.
|
1006 |
-
* Fixed bug: Small random error when viewing the licenses page.
|
1007 |
-
|
1008 |
-
= 4.6.4 (2014-11-10) =
|
1009 |
-
* Enhanced: Added filters to the custom feed.
|
1010 |
-
* Enhanced: Updated some styles to improve the user interface.
|
1011 |
-
* Fixed bug: The "Remove selected from Blacklist" button had no nonce associated with it.
|
1012 |
-
* Fixed bug: The Blacklist menu entry was not always being shown.
|
1013 |
-
|
1014 |
-
= 4.6.3 (2014-11-3) =
|
1015 |
-
Enhanced: Re-added the "Add New" link in the plugin's menu.
|
1016 |
-
Enhanced: Improved error logging.
|
1017 |
-
Enhanced: Bulk actions in the Feed Sources page are now also included in the bottom dropdown menu.
|
1018 |
-
Fixed bug: Add-on updater was prone to conflicts. Now enclosed in an action.
|
1019 |
-
Fixed bug: The Full Text RSS Feeds add-on was not showing as active in the "Add-ons" page.
|
1020 |
-
Fixed bug: Broken links in the "Add-ons" page, to add-on pages on our site.
|
1021 |
-
|
1022 |
-
= 4.6.2 (2014-10-15) =
|
1023 |
-
* Enhanced: Improved plugin responsiveness.
|
1024 |
-
* Enhanced: Updated some help text in tooltips with better explainations and added clarity.
|
1025 |
-
* Enhanced: Optimized some old SQL queries.
|
1026 |
-
* Enhanced: Added better debug logging.
|
1027 |
-
* Enhanced: Added a new filter to modify the text shown before author names.
|
1028 |
-
* Fixed bug: Licenses were not showing as active, even though they were activated.
|
1029 |
-
|
1030 |
-
= 4.6.1 (2014-10-06) =
|
1031 |
-
* Enhanced: Improved internationalization in the plugin, for better translations.
|
1032 |
-
* Fixed bug: If the feed source age limit was left empty, the global setting was used instead of ignoring the limit.
|
1033 |
-
|
1034 |
-
= 4.6 (2014-09-22) =
|
1035 |
-
* Enhanced: Improved the user interface, with better responsiveness and tooltips.
|
1036 |
-
* Enhanced: Removes the ID column. The ID is now shown fixed in row actions.
|
1037 |
-
* Enhanced: Feed Preview indicates if feed items have no dates.
|
1038 |
-
* Fixed bug: If a feed item has no date, the date and time it was imported is used.
|
1039 |
-
|
1040 |
-
= 4.5.3 (2014-09-15) =
|
1041 |
-
* New Featured: Added filter to allow adding RSS feeds to the head of your site's pages for CPTs.
|
1042 |
-
* Enhanced: Columns in the feed sources table are now sortable.
|
1043 |
-
* Enhanced: Removed the ID column in the feed sources table. The ID has been moved as a row action.
|
1044 |
-
* Enhanced: Improved various interface elements.
|
1045 |
-
* Enhanced: Better responsiveness for smaller screen.
|
1046 |
-
* Fixed bug: The importing spinning icon would get stuck and spin for a very long time.
|
1047 |
-
* Fixed bug: Removed an old description meta field.
|
1048 |
-
* Fixed bug: Plugin was not removing all scheduled cron jobs when deactivated.
|
1049 |
-
|
1050 |
-
= 4.5.2 (2014-09-09) =
|
1051 |
-
* Enhanced: Optimized plugin for WordPress 4.0.
|
1052 |
-
* Enhanced: Improved template and added filters for add-on hooking.
|
1053 |
-
* Fixed bug: Editor toolbar visible over the WP RSS shortcode dialog.
|
1054 |
-
|
1055 |
-
= 4.5.1 (2014-08-26) =
|
1056 |
-
* Fixed bug: Last import feed item count stays at zero.
|
1057 |
-
* Fixed bug: Datetime::setTimestamp error when using PHP 5.2 or earlier.
|
1058 |
-
* Fixed bug: The display limit was not working.
|
1059 |
-
* Fixed bug: Minor bug in licensing.
|
1060 |
-
|
1061 |
-
= 4.5 (2014-08-25) =
|
1062 |
-
* New Feature: Bulk importer allows you to create multiple feed sources at once.
|
1063 |
-
* Enhanced: Improved OPML importer with added hooks.
|
1064 |
-
* Enhanced: Centralized add-on licensing, fixing multiple bugs.
|
1065 |
-
* Fixed bug: Undefined `feed_limit` errors when using the shortcode.
|
1066 |
-
|
1067 |
-
= 4.4.4 (2014-08-19) =
|
1068 |
-
* Fixed bug: Errors when using older PHP versions 5.3 or lower.
|
1069 |
-
|
1070 |
-
= 4.4.3 (2014-08-19) =
|
1071 |
-
* Fixed bug: Errors when using older PHP versions 5.3 or lower.
|
1072 |
-
|
1073 |
-
= 4.4.2 (2014-08-19) =
|
1074 |
-
* Fixed bug: Errors when using older PHP versions 5.3 or lower.
|
1075 |
-
|
1076 |
-
= 4.4.1 (2014-08-18) =
|
1077 |
-
* Enhanced: Various improvements to the plugin interface and texts.
|
1078 |
-
* Enhanced: Moved the restore default settings button farther down the Debugging page, to avoid confusion with the delete button.
|
1079 |
-
* Fixed bug: Feed item dates were not being adjusted to the timezone when using a GMT offset.
|
1080 |
-
* Fixed bug: Feed item dates are now adjusted according to daylight savings time.
|
1081 |
-
|
1082 |
-
= 4.4 (2014-08-11) =
|
1083 |
-
* New Feature: Blacklist - delete items and blacklist them to never import them again.
|
1084 |
-
* Enhanced: Added a button in the Debugging page to reset the plugin settings to default.
|
1085 |
-
* Enhanced: WordPress Yoast SEO metaboxes and custom columns will no longer appear.
|
1086 |
-
|
1087 |
-
= 4.3.1 (2014-08-08) =
|
1088 |
-
* Enhanced: Better wording on settings page.
|
1089 |
-
* Fixed bug: The Links Behaviour option in the settings was not working.
|
1090 |
-
* Fixed bug: The wrong feed items were being shown for some sources when using the "View Items" row action.
|
1091 |
-
|
1092 |
-
= 4.3 (2014-08-04) =
|
1093 |
-
* New Feature: Feed items now also import authors.
|
1094 |
-
* Enhanced: Custom feed is now in RSS 2.0 format.
|
1095 |
-
* Enhanced: Improved the display template for feed items.
|
1096 |
-
* Fixed bug: Custom feed was not working in Firefox.
|
1097 |
-
* Fixed bug: Some feed items were showing items from another feed source.
|
1098 |
-
* Fixed bug: The feed limit in the global settings was not working.
|
1099 |
-
|
1100 |
-
= 4.2.3 (2014-07-29) =
|
1101 |
-
* Enhanced: Added an option to choose between the current pagination type, and numbered pagination.
|
1102 |
-
* Enhanced: The Feed Preview now also shows the total number of items in the feed.
|
1103 |
-
* Fixed bug: A PHP warning error was being shown in the System Info.
|
1104 |
-
* Fixed bug: Language files were not always being referenced correctly.
|
1105 |
-
* Fixed bug: Manually fetching a feed fails if the feed is scheduled to update in the next 10 minutes.
|
1106 |
-
* Fixed bug: Bing RSS feeds were importing duplicates on every update.
|
1107 |
-
|
1108 |
-
= 4.2.2 (2014-07-23) =
|
1109 |
-
* Enhanced: Facebook page feeds are now changed into RSS 2.0 feeds, rather than Atom 1.0 feeds.
|
1110 |
-
* Enhanced: Improved live updating performace on the Feed Sources page.
|
1111 |
-
|
1112 |
-
= 4.2.1 (2014-07-17) =
|
1113 |
-
* Enhanced: Feed Sources page is now more responsive.
|
1114 |
-
|
1115 |
-
= 4.2 (2014-07-17) =
|
1116 |
-
* New Feature: Can now view each feed source's imported feed items separate from other feed sources' feed items.
|
1117 |
-
* Enhanced: Major visual update to the Feed Sources page with new live updates.
|
1118 |
-
* Enhanced: The custom feed now includes the feed source.
|
1119 |
-
* Fixed bug: Google News feeds were importing duplicate items on every update.
|
1120 |
-
* Fixed bug: Multiple minor bug fixes with old filters.
|
1121 |
-
|
1122 |
-
= 4.1.6 (2014-06-28) =
|
1123 |
-
* Fixed bug: Results returned by wprss_get_feed_items_for_source() will no longer be affected by filters.
|
1124 |
-
* Fixed bug: Charset issue in titles
|
1125 |
-
|
1126 |
-
= 4.1.5 (2014-06-19) =
|
1127 |
-
* Enhanced: The Feed Sources table now indicates which feed sources encountered errors during the last import.
|
1128 |
-
* Fixed bug: Feed titles were not being decoded for HTML entities.
|
1129 |
-
|
1130 |
-
= 4.1.4 (2014-05-16) =
|
1131 |
-
* Enhanced: Minor improvements to feed importing and handling.
|
1132 |
-
* Fixed bug: HTML entities were not being decoded in feed item titles.
|
1133 |
-
|
1134 |
-
= 4.1.3 (2014-04-28) =
|
1135 |
-
* Enhanced: Added a force feed option, for valid RSS feeds with incorrect header content types.
|
1136 |
-
* Fixed bug: HTML entities in feed item titles are now being decoded.
|
1137 |
-
|
1138 |
-
= 4.1.2 (2014-04-22) =
|
1139 |
-
* Enhanced: Improved the custom feed, by allowing a custom title.
|
1140 |
-
* Enhanced: Improved shortcode, by adding the "pagination" parameter.
|
1141 |
-
* Enhanced: Modified a filter to fix some bugs in the add-ons.
|
1142 |
-
|
1143 |
-
= 4.1.1 (2014-04-09) =
|
1144 |
-
* Enhanced: Tracking notices only appear for admin users.
|
1145 |
-
* Fixed bug: Auto Feed Discovery was not working.
|
1146 |
-
|
1147 |
-
= 4.1 (2014-04-03) =
|
1148 |
-
* New Feature: Feed items can now link to enclosure links in the feed.
|
1149 |
-
* Enhanced: Added a filter to allow add-ons to modify feed item queries.
|
1150 |
-
|
1151 |
-
= 4.0.9 (2014-03-27) =
|
1152 |
-
* Enhanced: Added a filter to modify the feeds template.
|
1153 |
-
* Fixed bug: Nested lists in feeds template.
|
1154 |
-
|
1155 |
-
= 4.0.8 (2014-03-20) =
|
1156 |
-
* Fixed bug: Using the shortcode makes the comments section always open.
|
1157 |
-
|
1158 |
-
= 4.0.7 (2014-03-08) =
|
1159 |
-
* Fixed bug: The plugin prevented uploading of header images.
|
1160 |
-
|
1161 |
-
= 4.0.6 (2014-03-05) =
|
1162 |
-
* Fixed bug: Hook change in last version suspected reason for some installations having non-updated feed items.
|
1163 |
-
|
1164 |
-
= 4.0.5 (2014-03-03) =
|
1165 |
-
* New Feature: Time ago added as an option.
|
1166 |
-
* Enhanced: The plugin now allows the use of RSS and Atom feeds that do not specify the correct MIME type.
|
1167 |
-
* Enhanced: Better performance due to better hook usage.
|
1168 |
-
* Fixed bug: Facebook page feed URL conversion was not being triggered for new feed sources.
|
1169 |
-
* Fixed bug: Styles fix for pagination.
|
1170 |
-
* Fixed bug: Removed empty spaces in logging.
|
1171 |
-
|
1172 |
-
= 4.0.4 (2014-02-17) =
|
1173 |
-
* Enhanced: Added Activate/Pause bulk actions in the Feed Sources page.
|
1174 |
-
* Enhanced: Feed Sources page table has been re-designed.
|
1175 |
-
* Enhanced: Logging is now site dependant on multisite.
|
1176 |
-
* Fixed bug: Undefined display settings where appearing on the front end.
|
1177 |
-
|
1178 |
-
= 4.0.3 (2014-02-12) =
|
1179 |
-
* Fixed bug: The general setting for deleting feed items by age was not working.
|
1180 |
-
|
1181 |
-
= 4.0.2 (2014-02-10) =
|
1182 |
-
* Enhanced: Added a filter to change the html tags allowed in feed item content.
|
1183 |
-
|
1184 |
-
= 4.0.1 (2014-02-08) =
|
1185 |
-
* Fixed bug: Empty array of feed items bug caused importing problems.
|
1186 |
-
|
1187 |
-
= 4.0 (2014-02-04) =
|
1188 |
-
* Enhanced: Improved some internal queries, for better performance.
|
1189 |
-
* Fixed bug: Feed limits were not working properly.
|
1190 |
-
|
1191 |
-
= 3.9.9 (2014-02-03) =
|
1192 |
-
* Enhanced: The custom feed can now be extended by add-ons.
|
1193 |
-
|
1194 |
-
= 3.9.8 (2014-01-20) =
|
1195 |
-
* Fixed bug: Removed excessive logging from Debugging Error Log.
|
1196 |
-
|
1197 |
-
= 3.9.7 (2014-01-17) =
|
1198 |
-
* Fixed bug: Bug in admin-debugging.php causing trouble with admin login
|
1199 |
-
|
1200 |
-
= 3.9.6 (2014-01-17) =
|
1201 |
-
* Enhanced: Added error logging.
|
1202 |
-
|
1203 |
-
= 3.9.5 (2014-01-02) =
|
1204 |
-
* Enhanced: Added a feed validator link in the New/Edit Feed Sources page.
|
1205 |
-
* Enhanced: The Next Update column also shows the time remaining for next update, for feed source on the global update interval.
|
1206 |
-
* Enhanced: The custom feed has been improved, and is now identical to the feeds displayed with the shortcode.
|
1207 |
-
* Enhanced: License notifications only appear on the main site when using WordPress multisite.
|
1208 |
-
* Enhanced: Updated Colorbox script to 1.4.33
|
1209 |
-
* Fixed bug: The Imported Items column was always showing zero.
|
1210 |
-
* Fixed bug: Feed items not being imported with limit set to zero. Should be unlimited.
|
1211 |
-
* Fixed bug: Fat header in Feed Sources page
|
1212 |
-
|
1213 |
-
= 3.9.4 (2013-12-24) =
|
1214 |
-
* Enhanced: Added a column in the Feed Sources page that shows the number of feed items imported for each feed source.
|
1215 |
-
* Fixed bug: Leaving the delete old feed items empty did not ignore the delete.
|
1216 |
-
|
1217 |
-
= 3.9.3 (2013-12-23) =
|
1218 |
-
* Fixed bug: Fixed tracking pointer appearing on saving settings.
|
1219 |
-
|
1220 |
-
= 3.9.2 (2013-12-21) =
|
1221 |
-
* Fixed bug: Incorrect file include call.
|
1222 |
-
|
1223 |
-
= 3.9.1 (2013-12-12) =
|
1224 |
-
* Enhanced: Improved date and time handling for imported feed items.
|
1225 |
-
* Fixed bug: Incorrect values being shown in the Feed Processing metabox.
|
1226 |
-
* Fixed bug: Feed limits set to zero were causing feeds to not be imported.
|
1227 |
-
|
1228 |
-
= 3.9 (2013-12-12) =
|
1229 |
-
* New Feature: Feed sources can have their own update interval.
|
1230 |
-
* New Feature: The time remaining until the next update has been added to the Feed Source table.
|
1231 |
-
|
1232 |
-
= 3.8 (2013-12-05) =
|
1233 |
-
* New Feature: Feed items can be limited and deleted by their age.
|
1234 |
-
* Enhanced: Added utility functions for shorter filters.
|
1235 |
-
* Fixed bug: License codes were being erased when add-ons were deactivated.
|
1236 |
-
* Fixed bug: Some feed sources could not be set to active from the table controls.
|
1237 |
-
* Fixed bug: str_pos errors appear when custom feed url is left empty.
|
1238 |
-
* Fixed bug: Some options were producing undefined index errors.
|
1239 |
-
|
1240 |
-
= 3.7 (2013-11-28) =
|
1241 |
-
* New Feature: State system - Feed sources can be activated/paused.
|
1242 |
-
* New Feature: State system - Feed sources can be set to activate or pause themselves at a specific date and time.
|
1243 |
-
* Enhanced: Added compatibility with nested outline elements in OPML files.
|
1244 |
-
* Enhanced: Admin menu icon image will change into a Dashicon, when WordPress is updated to 3.8 (Decemeber 2013).
|
1245 |
-
* Fixed bug: Custom Post types were breaking when the plugin is activated.
|
1246 |
-
|
1247 |
-
= 3.6.1 (2013-11-17) =
|
1248 |
-
* Fixed bug: Missing 2nd argument for wprss_shorten_title()
|
1249 |
-
|
1250 |
-
= 3.6 (2013-11-16) =
|
1251 |
-
* New Feature: Can set the maximum length for titles. Long titles get trimmed.
|
1252 |
-
* Fixed bug: Fixed errors with undefined indexes for unchecked checkboxes in the settings page.
|
1253 |
-
* Fixed bug: Pagination on front static page was not working.
|
1254 |
-
|
1255 |
-
= 3.5.2 (2013-11-11) =
|
1256 |
-
* Fixed bug: Invalid feed source url was producing an Undefined method notice.
|
1257 |
-
* Fixed bug: Custom feed was producing a 404 page.
|
1258 |
-
* Fixed bug: Presstrends code firing on admin_init, opt-in implementation coming soon
|
1259 |
-
|
1260 |
-
= 3.5.1 (2013-11-09) =
|
1261 |
-
* Enhanced: Increased compatibility with RSS sources.
|
1262 |
-
* Fixed bug: Pagination not working on home page
|
1263 |
-
|
1264 |
-
= 3.5 (2013-11-6) =
|
1265 |
-
* New Feature: Can delete feed items for a particular source
|
1266 |
-
* Enhanced: the 'Fetch feed items' row action for feed sources resets itself after 3.5 seconds.
|
1267 |
-
* Enhanced: The feed image is saved for each url.
|
1268 |
-
* Fixed bug: Link to source now links to correct url. Previously linked to site's feed.
|
1269 |
-
|
1270 |
-
= 3.4.6 (2013-11-1) =
|
1271 |
-
* Enhanced: Added more hooks to debugging page for the Feed to Post add-on.
|
1272 |
-
* Fixed bug: Uninitialized loop index
|
1273 |
-
|
1274 |
-
= 3.4.5 (2013-10-30) =
|
1275 |
-
* Bug Fix: Feed items were not being imported while the WPML plugin was active.
|
1276 |
-
|
1277 |
-
= 3.4.4 (2013-10-26) =
|
1278 |
-
* New feature: Pagination
|
1279 |
-
* New feature: First implementation of editor button for easy shortcode creation
|
1280 |
-
* Enhanced: Feed items and sources don't show up in link manager
|
1281 |
-
* Enhanced: Included Presstrends code for plugin usage monitoring
|
1282 |
-
|
1283 |
-
= 3.4.3 (2013-10-20) =
|
1284 |
-
* Fixed bug: Removed anonymous functions for backwards PHP compatibility
|
1285 |
-
* Bug fix: Added suppress_filters in feed-display.php to prevent a user reported error
|
1286 |
-
* Bug fix: Missing <li> in certain feed displays
|
1287 |
-
|
1288 |
-
= 3.4.2 (2013-9-19) =
|
1289 |
-
* Enhanced: Added some hooks for Feed to Post compatibility
|
1290 |
-
* Enhanced: Moved date settings to a more appropriate location
|
1291 |
-
|
1292 |
-
= 3.4.1 (2013-9-16) =
|
1293 |
-
* Fixed Bug: Minor issue with options page - PHP notice
|
1294 |
-
|
1295 |
-
= 3.4 (2013-9-15) =
|
1296 |
-
* New Feature: Saving/Updating a feed source triggers an update for that source's feed items.
|
1297 |
-
* New Feature: Option to change Youtube, Vimeo and Dailymotion feed item URLs to embedded video players URLs
|
1298 |
-
* New Feature: Facebook Pages URLs are automatically detected and changed into Atom Feed URLs using FB's Graph
|
1299 |
-
* Enhanced: Updated jQuery Colorbox library to 1.4.29
|
1300 |
-
* Fixed Bug: Some settings did not have a default value set, and were throwing an 'Undefined Index' error
|
1301 |
-
* Fixed Bug: Admin notices do not disappear immediately when dismissed.
|
1302 |
-
|
1303 |
-
= Version 3.3.3 (2013-09-08) =
|
1304 |
-
* Fixed bug: Better function handling on uninstall, should remove uninstall issues
|
1305 |
-
|
1306 |
-
= Version 3.3.2 (2013-09-07) =
|
1307 |
-
* New feature: Added exclude parameter to shortcode
|
1308 |
-
* Enhanced: Added metabox links to documentation and add-ons
|
1309 |
-
* Fixed bug: Custom feed linking to post on user site rather than original source
|
1310 |
-
* Fixed bug: Custom post types issues when activitating the plugin
|
1311 |
-
|
1312 |
-
= Version 3.3.1 (2013-08-09) =
|
1313 |
-
* Fixed Bug: Roles and Capabilities file had not been included
|
1314 |
-
* Fixed Bug: Error on install, function not found
|
1315 |
-
|
1316 |
-
= Version 3.3 (2013-08-08) =
|
1317 |
-
* New feature: OPML importer
|
1318 |
-
* New feature: Feed item limits for individual Feed Sources
|
1319 |
-
* New feature: Custom feed URL
|
1320 |
-
* New feature: Feed limit on custom feed
|
1321 |
-
* New feature: New 'Fetch feed items' action for each Feed Source in listing display
|
1322 |
-
* New feature: Option to enable link to source
|
1323 |
-
* Enhanced: Date strings now change according to locale being used (i.e. compatible with WPML)
|
1324 |
-
* Enhanced: Capabilities implemented
|
1325 |
-
* Enhanced: Feed Sources row action 'View' removed
|
1326 |
-
* Fixed Bug: Proxy feed URLs resulting in the permalink: example.com/url
|
1327 |
-
|
1328 |
-
= Version 3.2 (2013-07-06) =
|
1329 |
-
* New feature: Parameter to limit number of feeds displayed
|
1330 |
-
* New feature: Paramter to limit feeds displayed to particular sources (via ID)
|
1331 |
-
* Enhanced: Better feed import handling to handle large number of feed sources
|
1332 |
-
|
1333 |
-
= Version 3.1.1 (2013-06-06) =
|
1334 |
-
* Fixed bug: Incompatibility with some other plugins due to function missing namespace
|
1335 |
-
|
1336 |
-
= Version 3.1 (2013-06-06) =
|
1337 |
-
* New feature: Option to set the number of feed items imported from every feed (default 5)
|
1338 |
-
* New feature: Import and Export aggregator settings and feed sources
|
1339 |
-
* New feature: Debugging page allowing manual feed refresh and feed reset
|
1340 |
-
* Enhanced: Faster handling of restoring sources from trash when feed limit is 0
|
1341 |
-
* Fixed bug: Limiter on number of overall feeds stored not working
|
1342 |
-
* Fixed bug: Incompatibility issue with Foobox plugin fixed
|
1343 |
-
* Fixed bug: Duplicate feeds sometimes imported
|
1344 |
-
|
1345 |
-
= Version 3.0 (2013-03-16) =
|
1346 |
-
* New feature: Option to select cron frequency
|
1347 |
-
* New feature: Code extensibility added to be compatible with add-ons
|
1348 |
-
* New feature: Option to set a limit to the number of feeds stored (previously 50, hard coded)
|
1349 |
-
* New feature: Option to define the format of the date shown below each feed item
|
1350 |
-
* New feature: Option to show or hide source of feed item
|
1351 |
-
* New feature: Option to show or hide publish date of feed item
|
1352 |
-
* New feature: Option to set text preceding publish date
|
1353 |
-
* New feature: Option to set text preceding source of feed item
|
1354 |
-
* New feature: Option to link title or not
|
1355 |
-
* New feature: Limit of 5 items imported for each source instead of 10
|
1356 |
-
* Enhanced: Performance improvement when publishing * New feeds in admin
|
1357 |
-
* Enhanced: Query tuning for better performance
|
1358 |
-
* Enhanced: Major code rewrite, refactoring and inclusion of hooks
|
1359 |
-
* Enhanced: Updated Colorbox to v1.4.1
|
1360 |
-
* Enhanced: Better security implementations
|
1361 |
-
* Enhanced: Better feed preview display
|
1362 |
-
* Fixed bug: Deletion of items upon source deletion not working properly
|
1363 |
-
* Requires: WordPress 3.3
|
1364 |
-
|
1365 |
-
= Version 2.2.3 (2012-11-01) =
|
1366 |
-
* Fixed bug: Tab navigation preventing typing in input boxes
|
1367 |
-
* Removed: Feeds showing up in internal linking pop up
|
1368 |
-
|
1369 |
-
= Version 2.2.2 (2012-10-30) =
|
1370 |
-
* Removed: Feeds showing up in site search results
|
1371 |
-
* Enhanced: Better tab button navigation when adding a new feed
|
1372 |
-
* Enhanced: Better guidance when a feed URL is invalid
|
1373 |
-
|
1374 |
-
= Version 2.2.1 (2012-10-17) =
|
1375 |
-
* Fixed bug: wprss_feed_source_order assumes everyone is an admin
|
1376 |
-
|
1377 |
-
= Version 2.2 (2012-10-01) =
|
1378 |
-
* Italian translation added
|
1379 |
-
* Feed source order changed to alphabetical
|
1380 |
-
* Fixed bug - repeated entries when having a non-valid feed source
|
1381 |
-
* Fixed bug - all imported feeds deleted upon trashing a single feed source
|
1382 |
-
|
1383 |
-
= Version 2.1 (2012-09-27) =
|
1384 |
-
* Now localised for translations
|
1385 |
-
* Fixed bug with date string
|
1386 |
-
* Fixed $link_before and $link_after, now working
|
1387 |
-
* Added backwards compatibility for wp_rss_aggregator() function
|
1388 |
-
|
1389 |
-
= Version 2.0 (2012-09-21) =
|
1390 |
-
* Bulk of code rewritten and refactored
|
1391 |
-
* Added install and upgrade functions
|
1392 |
-
* Added DB version setting
|
1393 |
-
* Feed sources now stored as Custom Post Types
|
1394 |
-
* Feed source list sortable ascending or descending by name
|
1395 |
-
* Removed days subsections in feed display
|
1396 |
-
* Ability to limit total number of feeds displayed
|
1397 |
-
* Feeds now fetched via Cron
|
1398 |
-
* Cron job to delete old feed items, keeps max of 50 items in DB
|
1399 |
-
* Now requires WordPress 3.2
|
1400 |
-
* Updated colorbox to v1.3.20.1
|
1401 |
-
* Limit of 15 items max imported for each source
|
1402 |
-
* Fixed issue of page content displaying incorrectly after feeds
|
1403 |
-
|
1404 |
-
= Version 1.1 (2012-08-13) =
|
1405 |
-
* Now requires WordPress 3.0
|
1406 |
-
* More flexible fetching of images directory
|
1407 |
-
* Has its own top level menu item
|
1408 |
-
* Added settings section
|
1409 |
-
* Ability to open in lightbox, new window or default browser behaviour
|
1410 |
-
* Ability to set links as follow or no follow
|
1411 |
-
* Using constants for oftenly used locations
|
1412 |
-
* Code refactoring
|
1413 |
-
* Changes in file and folder structure
|
1414 |
-
|
1415 |
= Version 1.0 (2012-01-06) =
|
1416 |
* Initial release.
|
3 |
Plugin URI: http://www.wprssaggregator.com
|
4 |
Tags: rss, aggregation, autoblog, autoblog aggregator, autoblogger, autoblogging, autopost, content curation, feed aggregation, feed aggregator, feed import, feed reader, feed to post, feeds, multi feed import, multi feed importer, multi rss feeds, multiple feed import, multiple rss feeds,rss aggregator, rss feader, RSS Feed, rss feed to post, rss feeder, RSS import, rss multi importer, rss post importer, rss retriever, rss to post, syndication
|
5 |
Requires at least: 4.0
|
6 |
+
Tested up to: 4.4.1
|
7 |
+
Stable tag: 4.8.1
|
8 |
License: GPLv2 or later
|
9 |
+
WP RSS Aggregator is the No.1 RSS feed importer and autoblogging plugin for WordPress. It provides the most comprehensive and elegant solution to import RSS feeds with premium add-ons available for additional functionality.
|
10 |
|
11 |
|
12 |
== Description ==
|
13 |
|
14 |
+
WP RSS Aggregator is the original and best plugin for importing, merging and displaying RSS and Atom feeds on your WordPress site. It’s the most comprehensive and elegant RSS feed solution for WordPress.
|
15 |
|
16 |
+
With this free core version of WP RSS Aggregator you’ll be able to aggregate as many RSS feeds from as many sources as you'd like. Using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) you can then display the imported feed items from one or more sources directly on your website.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
= Highlighted Features =
|
19 |
|
20 |
+
* Set a name for each feed source.
|
21 |
+
* Import any number of feed items from multiple RSS Feeds.
|
22 |
+
* Display feed items using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) or by [calling the display function from within your theme](http://docs.wprssaggregator.com/shortcodes/#using-shortcodes-directly-in-templates).
|
23 |
+
* Limit the age of the feed items stored in the database.
|
24 |
+
* Set the number of feed items per feed source that you want to show and store.
|
25 |
+
* Set the pagination for the displayed feed items.
|
26 |
+
* Set a general feed import time interval.
|
27 |
+
* Schedule feed imports for each individual feed source.
|
28 |
+
* Choose whether to show/hide feed sources and dates, and set the date format.
|
29 |
+
* Set the links as no-follow or not, or add no follow to the meta tag.
|
30 |
+
* Customise the output using various [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#core-parameters).
|
31 |
+
* Set the open link behaviour (lightbox, new window or current window).
|
32 |
+
* Opens YouTube, DailyMotion and Vimeo videos directly.
|
33 |
+
* Export a custom RSS feed based on your feed sources.
|
34 |
+
* Extendable via [action and filter hooks](http://docs.wprssaggregator.com/category/developer-documentation/filters/).
|
35 |
+
* Incorporates feed auto-discovery, which lets you add feed sources without knowing the exact URL.
|
36 |
+
* Integrated with the Simplepie library that comes with WordPress. This includes RSS 0.91 and RSS 1.0 formats, the popular RSS 2.0 format, Atom etc.
|
37 |
|
38 |
= Premium Add-Ons =
|
39 |
+
WP RSS Aggregator also has a number of premium add-ons that add more functionality to the core plugin. They provide the means to create autoblogging websites, display job listings, import YouTube videos and a lot more. Take a look at our [Use Cases](http://www.wprssaggregator.com/use-cases/) and our [Showcase](http://www.wprssaggregator.com/showcase/) for more ideas. Here are the add-ons currently available:
|
40 |
|
41 |
+
* [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) is an advanced importer that lets you import RSS feeds directly into WordPress posts or any other custom post type. You can use it to populate a website in minutes (autoblog). This is the most popular and feature-filled extension.
|
42 |
+
* [Keyword Filtering](http://www.wprssaggregator.com/extension/keyword-filtering/) filters the feed items to be imported based on keywords, key phrases or tags, so you only get the items you're interested in.
|
43 |
+
* [Excerpts & Thumbnails](http://www.wprssaggregator.com/extension/excerpts-thumbnails/) displays an excerpt and thumbnail image (taken from within the RSS feed) together with the title, date and source of each feed item.
|
44 |
+
* [Categories](http://www.wprssaggregator.com/extension/categories/) categorises your feed sources and allows you to display feed items from a particular category within your site using the [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#categories-parameters).
|
45 |
+
* [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) adds connectivity to our Full Text Premium service, which allows you to import the full post content for an unlimited number of feed items per feed source, even when the feed itself doesn’t provide it. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/))
|
46 |
+
* [WordAi](http://www.wprssaggregator.com/extension/wordai/) allows you to take an RSS feed and turn it into new content that is both completely unique and completely readable. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) and a [WordAi account](https://wordai.com/))
|
47 |
+
* [Widget](http://www.wprssaggregator.com/extension/widget/) adds a widget to your website that displays the imported feed items. It can also display excerpts and thumbnail images when used in conjunction with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extension/excerpts-thumbnails/) add-on.
|
48 |
+
* [SpinnerChief](http://www.wprssaggregator.com/extension/spinnerchief/) An extension for [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) that allows you to integrate the SpinnerChief article spinner so that the imported content is both completely unique and completely readable.
|
49 |
|
50 |
+
[View a comparison of our three most popular add-ons here](http://www.wprssaggregator.com/product-comparison/). If you're unsure as to which add-ons you need, [we put together this post to help you out](http://www.wprssaggregator.com/add-ons-purchase/).
|
51 |
+
|
52 |
+
There are also two premium bundles available, the [Simple Feeds Bundle](http://www.wprssaggregator.com/extension/simple-feeds-bundle/) and the [Advanced Feeds Bundle](http://www.wprssaggregator.com/extension/advanced-feeds-bundle/). [View a quick comparison of these bundles here](http://www.wprssaggregator.com/bundle-comparison/).
|
53 |
+
|
54 |
+
We also provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service that allows you to generate RSS feeds from any webpage, even if it doesn't have its own RSS feed.
|
55 |
|
56 |
= Demo =
|
57 |
+
The core plugin can be seen in use [on our website's demo page](http://www.wprssaggregator.com/demo/). There are also a number of [other demos](http://www.wprssaggregator.com/) available for our premium add-ons.
|
58 |
|
59 |
= Video Walkthrough =
|
60 |
+
Have a look at the core version of WP RSS Aggregator below, or [go here to view our introductory videos for the premium add-ons](http://docs.wprssaggregator.com/introductory-videos/).
|
61 |
[youtube http://www.youtube.com/watch?v=fcENPsmJbvc]
|
62 |
|
63 |
= Documentation =
|
64 |
+
Our [comprehensive documentation](http://docs.wprssaggregator.com/) provides you with everything you need to install, set up and customize the plugin to your needs. You can also browse through [a large number of FAQs](http://docs.wprssaggregator.com/category/faqs/) that cover almost everything there is to ask.
|
65 |
|
66 |
= As featured on =
|
67 |
+
* [WP Mayor](http://www.wpmayor.com/rss-feeds-review-wp-rss-aggregator/)
|
68 |
+
* [LatestWP](http://www.latestwp.com/2015/03/15/wp-rss-aggregator-plugin-review/)
|
69 |
+
* [WPBeginner](http://www.wpbeginner.com/plugins/how-to-fetch-feeds-in-wordpress-using-wp-rss-aggregator/)
|
70 |
+
* [WPExplorer](http://www.wpexplorer.com/custom-rss-aggregator-plugin/)
|
71 |
+
* [WPKube](http://www.wpkube.com/wp-rss-aggregator-wordpress-review/)
|
72 |
+
* [Torque](http://torquemag.io/wp-rss-aggregator-review-do-more-with-rss-feeds/)
|
73 |
+
* [MyWPexpert](http://www.mywpexpert.com/wordpress-rss-aggregator-plugin)
|
74 |
* [Kikolani](http://kikolani.com/create-latest-posts-portfolio-page-wp-rss-aggregator.html)
|
75 |
+
* [ManageWP Plugin of the Month](http://managewp.com/free-wordpress-plugins-march-2014)
|
76 |
+
* [Tidy Repo](http://tidyrepo.com/wp-rss-aggregator/)
|
77 |
+
* [WPEka](http://www.wpeka.com/wp-rss-aggregators-plugin.html)
|
78 |
+
* [IndexWP](http://www.indexwp.com/wp-rss-aggregator-plugin-review/)
|
79 |
* [WPulsar](http://www.wpulsar.com/wp-rss-aggregator-plugin-feed-to-posts-keyword-filtering-review/)
|
80 |
* [Kevin Muldoon](http://www.kevinmuldoon.com/wp-rss-aggregator-wordpress-plugin/)
|
81 |
|
87 |
|
88 |
== Installation ==
|
89 |
|
90 |
+
1. Upload the `wp-rss-aggregator` folder to the `/wp-content/plugins/` directory.
|
91 |
+
2. Activate the WP RSS Aggregator plugin from the 'Plugins' section in your dashboard.
|
92 |
3. Configure the plugin by going to the `RSS Aggregator` menu item that appears in your dashboard menu.
|
93 |
+
4. Use the shortcode in your posts or pages: `[wp-rss-aggregator]`
|
94 |
+
|
95 |
+
You can easily select the source for your feeds and also insert a limit via [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#core-parameters) as shown below. To get your feed source ID please refer to the ID column in your feed source listing page.
|
96 |
|
97 |
+
`[wp-rss-aggregator source=”<ID>” limit=”<num>”]`
|
98 |
|
99 |
+
An example of a shortcode parameter in use could be:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
|
|
101 |
`[wp_rss_aggregator link_before='<li class="feed-link">' link_after='</li>']`
|
|
|
102 |
|
103 |
+
It is advisable to use the 'HTML' view of the editor when inserting shortcodes with parameters.
|
104 |
|
105 |
__Usage within theme files__
|
106 |
|
107 |
+
Here are two examples of a function call from within the theme's files:
|
108 |
`
|
109 |
<?php
|
110 |
wprss_display_feed_items( $args = array(
|
146 |
|
147 |
= Why do I get “No feed items found” when I insert the shortcode on a page or post? =
|
148 |
|
149 |
+
Try adding a few more feed sources and make sure they are valid by using the RSS Feed Validator.
|
150 |
|
151 |
Secondly make sure your WordPress cron system is working well. If not, the feeds cannot be imported. If in doubt you can go to RSS Aggregator > Debugging and hit the red button to re-import all feed items. If the problem persists contact support.
|
152 |
|
162 |
|
163 |
Sure! We wrote a [post](http://www.wprssaggregator.com/add-ons-purchase/) just for you. Read about which add-ons you should buy, we explain the different types of usage so you’ll know what to expect when purchasing.
|
164 |
|
165 |
+
If you need any further help you can [contact our support team](http://www.wprssaggregator.com/contact/).
|
166 |
|
167 |
= Where can I find the documentation for the plugin? =
|
168 |
|
169 |
+
Our complete documentation with FAQs included can be found on [our dedicated documentation website](http://docs.wprssaggregator.com/).
|
170 |
|
171 |
|
172 |
== Screenshots ==
|
186 |
|
187 |
== Changelog ==
|
188 |
|
189 |
+
= 4.8.1 (2016-02-02) =
|
190 |
+
* Fixed bug: Some exceptions used to cause fatal errors.
|
191 |
+
* Fixed bug: Requests made by image caching used to always have an infinite timeout.
|
192 |
+
* Fixed bug: Licensing algorithm used to use constants of inactive plugins, causing fatal error.
|
193 |
+
* Enhanced: Visual improvements.
|
194 |
+
* Enhanced: Included new Object Oriented code.
|
195 |
+
|
196 |
= 4.8 (2015-12-30) =
|
197 |
* Fixed bug: Licensing notices will now be displayed again.
|
198 |
* Enhanced: Major licensing system improvements.
|
709 |
* Code refactoring
|
710 |
* Changes in file and folder structure
|
711 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
712 |
= Version 1.0 (2012-01-06) =
|
713 |
* Initial release.
|
wp-rss-aggregator.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP RSS Aggregator
|
4 |
Plugin URI: http://www.wprssaggregator.com
|
5 |
Description: Imports and aggregates multiple RSS Feeds using SimplePie
|
6 |
-
Version: 4.8
|
7 |
Author: Jean Galea
|
8 |
Author URI: http://www.wprssaggregator.com
|
9 |
License: GPLv2
|
@@ -29,7 +29,7 @@
|
|
29 |
|
30 |
/**
|
31 |
* @package WPRSSAggregator
|
32 |
-
* @version 4.8
|
33 |
* @since 1.0
|
34 |
* @author Jean Galea <info@wprssaggregator.com>
|
35 |
* @copyright Copyright (c) 2012-2015, Jean Galea
|
@@ -43,7 +43,7 @@
|
|
43 |
|
44 |
// Set the version number of the plugin.
|
45 |
if( !defined( 'WPRSS_VERSION' ) )
|
46 |
-
define( 'WPRSS_VERSION', '4.8', true );
|
47 |
|
48 |
if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
|
49 |
define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
|
@@ -246,6 +246,59 @@
|
|
246 |
register_deactivation_hook( __FILE__ , 'wprss_deactivate' );
|
247 |
|
248 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
|
250 |
|
251 |
add_action( 'init', 'wprss_init' );
|
3 |
Plugin Name: WP RSS Aggregator
|
4 |
Plugin URI: http://www.wprssaggregator.com
|
5 |
Description: Imports and aggregates multiple RSS Feeds using SimplePie
|
6 |
+
Version: 4.8.1
|
7 |
Author: Jean Galea
|
8 |
Author URI: http://www.wprssaggregator.com
|
9 |
License: GPLv2
|
29 |
|
30 |
/**
|
31 |
* @package WPRSSAggregator
|
32 |
+
* @version 4.8.1
|
33 |
* @since 1.0
|
34 |
* @author Jean Galea <info@wprssaggregator.com>
|
35 |
* @copyright Copyright (c) 2012-2015, Jean Galea
|
43 |
|
44 |
// Set the version number of the plugin.
|
45 |
if( !defined( 'WPRSS_VERSION' ) )
|
46 |
+
define( 'WPRSS_VERSION', '4.8.1', true );
|
47 |
|
48 |
if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
|
49 |
define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
|
246 |
register_deactivation_hook( __FILE__ , 'wprss_deactivate' );
|
247 |
|
248 |
|
249 |
+
/**
|
250 |
+
* Returns the Spinnerchief Addon class singleton instance.
|
251 |
+
*
|
252 |
+
* @since 4.8.1
|
253 |
+
* @return Aventura\Wprss\Core\Plugin
|
254 |
+
*/
|
255 |
+
function wprss() {
|
256 |
+
static $plugin = null;
|
257 |
+
|
258 |
+
|
259 |
+
// One time initialization
|
260 |
+
if (is_null($plugin)) {
|
261 |
+
static $timesCalled = 0;
|
262 |
+
if ($timesCalled) {
|
263 |
+
throw new Exception('WP RSS Aggregator has been initialized recursively');
|
264 |
+
}
|
265 |
+
$timesCalled++;
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Basically, we could just do this here:
|
269 |
+
* Factory::create();
|
270 |
+
*
|
271 |
+
* However, the actual setup allows for even further customization.
|
272 |
+
* In fact, the factory can be substituted by some entirely different factory,
|
273 |
+
* that creates and initializes a different plugin in a different way.
|
274 |
+
*/
|
275 |
+
|
276 |
+
$factoryClassName = apply_filters('wprss_core_plugin_factory_class_name',
|
277 |
+
'Aventura\\Wprss\\Core\\Factory');
|
278 |
+
|
279 |
+
if (!class_exists($factoryClassName)) {
|
280 |
+
throw new Aventura\Wprss\Exception(
|
281 |
+
sprintf('Could not initialize add-on: Factory class "%1$s" does not exist', $factoryClassName));
|
282 |
+
}
|
283 |
+
|
284 |
+
$plugin = call_user_func_array(array($factoryClassName, 'create'), array(array(
|
285 |
+
'basename' => __FILE__,
|
286 |
+
'name' => 'WP RSS Aggregator'
|
287 |
+
)));
|
288 |
+
}
|
289 |
+
|
290 |
+
return $plugin;
|
291 |
+
}
|
292 |
+
|
293 |
+
require_once(WPRSS_INC . 'functions.php');
|
294 |
+
try {
|
295 |
+
$instance = wprss();
|
296 |
+
} catch (Exception $e) {
|
297 |
+
if (WP_DEBUG && WP_DEBUG_DISPLAY) {
|
298 |
+
throw $e;
|
299 |
+
}
|
300 |
+
wp_die( $e->getMessage() );
|
301 |
+
}
|
302 |
|
303 |
|
304 |
add_action( 'init', 'wprss_init' );
|