first commit

This commit is contained in:
2024-11-10 21:08:49 +01:00
commit 0d932ce5ee
14455 changed files with 2567501 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
# Joomunited Framework
## Potential backward compatibility issues from in 1.0.3
### Controller
#### exit_status method has been removed
Use existStatus method instead, parameters have not changed

View File

@@ -0,0 +1,21 @@
# This is a sample build configuration for PHP.
# Check our guides at https://confluence.atlassian.com/x/e8YWN for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: php:7.1.1
pipelines:
custom:
phpcs: &sharedphpcs
- step:
name: Phpcs
caches:
- composer
script:
- apt-get update && apt-get install -y unzip
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- composer install
- vendor/bin/phpcs -s .
branches:
'{master,development}': *sharedphpcs

View File

@@ -0,0 +1,8 @@
{
"require-dev": {
"squizlabs/php_codesniffer": "^3.2",
"wimg/php-compatibility": "*",
"wp-coding-standards/wpcs": "*"
},
"prefer-stable": true
}

View File

@@ -0,0 +1,161 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "c45f1d1b0944b1c1364cacfa0c25a5d9",
"packages": [],
"packages-dev": [
{
"name": "squizlabs/php_codesniffer",
"version": "3.2.3",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "4842476c434e375f9d3182ff7b89059583aa8b27"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4842476c434e375f9d3182ff7b89059583aa8b27",
"reference": "4842476c434e375f9d3182ff7b89059583aa8b27",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"bin": [
"bin/phpcs",
"bin/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Greg Sherwood",
"role": "lead"
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "http://www.squizlabs.com/php-codesniffer",
"keywords": [
"phpcs",
"standards"
],
"time": "2018-02-20T21:35:23+00:00"
},
{
"name": "wimg/php-compatibility",
"version": "8.1.0",
"source": {
"type": "git",
"url": "https://github.com/wimg/PHPCompatibility.git",
"reference": "4ac01e4fe8faaa4f8d3b3cd06ea92e5418ce472e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wimg/PHPCompatibility/zipball/4ac01e4fe8faaa4f8d3b3cd06ea92e5418ce472e",
"reference": "4ac01e4fe8faaa4f8d3b3cd06ea92e5418ce472e",
"shasum": ""
},
"require": {
"php": ">=5.3",
"squizlabs/php_codesniffer": "^2.2 || ^3.0.2"
},
"conflict": {
"squizlabs/php_codesniffer": "2.6.2"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0"
},
"suggest": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
},
"type": "phpcodesniffer-standard",
"autoload": {
"psr-4": {
"PHPCompatibility\\": "PHPCompatibility/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Wim Godden",
"role": "lead"
}
],
"description": "A set of sniffs for PHP_CodeSniffer that checks for PHP version compatibility.",
"homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
"keywords": [
"compatibility",
"phpcs",
"standards"
],
"time": "2017-12-27T21:58:38+00:00"
},
{
"name": "wp-coding-standards/wpcs",
"version": "0.14.1",
"source": {
"type": "git",
"url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git",
"reference": "cf6b310caad735816caef7573295f8a534374706"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/cf6b310caad735816caef7573295f8a534374706",
"reference": "cf6b310caad735816caef7573295f8a534374706",
"shasum": ""
},
"require": {
"php": ">=5.3",
"squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2"
},
"suggest": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
},
"type": "phpcodesniffer-standard",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Contributors",
"homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors"
}
],
"description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
"keywords": [
"phpcs",
"standards",
"wordpress"
],
"time": "2018-02-16T01:57:48+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": true,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}

View File

@@ -0,0 +1,49 @@
<?php
/*
JUPlugin Name: Joomunited WP Framework
Description: WP Framework for Joomunited extensions
Author: Joomunited
Version: 1.0.4
Author URI: http://www.joomunited.com
*/
defined('ABSPATH') || die();
// Prevent from loading julibraries twice
if (!defined('JU_LIBRARY_V1_0_4')) {
/**
* Julibrary autoloader method
*
* @param string $className Class name that should be loaded
*
* @return void
*/
function juLibrariesAutoload_v1_0_4($className)
{
$className = ltrim($className, '\\');
//Return if it's not a Joomunited's class
if (strpos($className, 'Joomunited') !== 0) {
return;
}
//Change Joomunited to the mu-plugin junited-libraries directory
$fileName = '';
$lastNsPos = strripos($className, '\\');
if ($lastNsPos) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName = 'ju-libraries' . substr($fileName, 10);
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
if (file_exists(dirname(__FILE__) . DIRECTORY_SEPARATOR . $fileName)) {
require dirname(__FILE__) . DIRECTORY_SEPARATOR . $fileName;
}
}
spl_autoload_register('juLibrariesAutoload_v1_0_4');
define('JU_LIBRARY_V1_0_4', true);
}

View File

@@ -0,0 +1,288 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Application
*/
class Application
{
/**
* Type of application, could be site or admin
*
* @var string
*/
protected $type = 'site';
/**
* Default controller task
*
* @var string
*/
protected $default_task = 'display';
/**
* Generated instances of application
*
* @var array
*/
protected static $instances = array();
/**
* Database object
*
* @var object
*/
protected $dbo;
/**
* Application instance name
* Generally the slug of the plugin using the framework
*
* @var string
*/
protected $name = '';
/**
* Path of the plugin using the framework
*
* @var string
*/
protected $path = '';
/**
* Plugin url
*
* @var string
*/
protected $url = '';
/**
* Is the application already initialized
*
* @var boolean
*/
protected $isinit = false;
/**
* Which last plugin did use the framework
*
* @var string
*/
protected static $lastUse = '';
/**
* Retrieve the application instance
*
* @param string $name Slug of plugin which requires the instance
* @param string $path Path of the plugin
* @param string $type Admin or Site application
*
* @return mixed
*/
public static function getInstance($name = null, $path = __FILE__, $type = null)
{
if ($name === null) {
$name = self::$lastUse;
}
if (!array_key_exists($name, self::$instances)) {
self::$instances[$name] = new Application();
self::$instances[$name]->name = $name;
self::$instances[$name]->path = plugin_dir_path($path);
self::$instances[$name]->url = plugins_url('', $path);
if ($type !== null) {
self::$instances[$name]->type = $type;
} elseif (is_admin()) {
if (defined('DOING_AJAX')) {
if (Utilities::getInput('juwpfisadmin', 'GET', 'string')) {
self::$instances[$name]->type = 'site';
} else {
self::$instances[$name]->type = 'admin';
}
} else {
self::$instances[$name]->type = 'admin';
}
} else {
self::$instances[$name]->type = 'site';
}
}
self::$lastUse = $name;
return self::$instances[$name];
}
/**
* Initialize the application
*
* @return void
*/
public function init()
{
if ($this->isinit === true) {
return;
}
//call app init file
$file = $this->getPath() . DIRECTORY_SEPARATOR . $this->getType() . DIRECTORY_SEPARATOR . 'init.php';
if (file_exists($file)) {
include($file);
}
//call filters
$file = $this->getPath() . DIRECTORY_SEPARATOR . $this->getType() . DIRECTORY_SEPARATOR . 'filters.php';
if (file_exists($file)) {
include($file);
$class = $this->getName() . 'Filter';
if (method_exists($class, 'load')) {
$filter = new $class();
$filter->load();
}
}
$this->isinit = true;
}
/**
* Get the name of the plugin using the application
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get path of the plugin using the application
*
* @param boolean $rel Retrieve relative path or full path
*
* @return string
*/
public function getPath($rel = false)
{
if ($rel) {
return str_replace(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR, '', $this->path . 'app');
} else {
return $this->path . DIRECTORY_SEPARATOR . 'app';
}
}
/**
* Execute a task
*
* @param null $default_task Default task
*
* @return void
*/
public function execute($default_task = null)
{
$task = Utilities::getInput('task');
if (empty($task) && $default_task !== null) {
$task = $default_task;
} else {
$task = strtolower($task);
}
$task = strtolower($task);
$split = explode('.', $task);
$controllerName = $split[0];
$taskName = count($split) > 1 ? $split[1] : '';
$fileController = Factory::getApplication()->getPath() . DIRECTORY_SEPARATOR . $this->type . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . $controllerName . '.php';
if (!file_exists($fileController)) {
Error::raiseError('404', 'Controller not found');
}
include_once $fileController;
$controllerClass = strtolower(Factory::getApplication()->getName()) . 'Controller' . ucfirst($controllerName);
$controller = new $controllerClass();
if (method_exists($controller, $taskName)) {
$controller->$taskName();
} elseif (property_exists($controller, 'default_task') && method_exists($controller, $controller->default_task)) {
$defaultTask = $controller->default_task;
$controller->$defaultTask();
} else {
Error::raiseError('404', 'Task not found');
}
}
/**
* Is the application an admin one
*
* @return boolean
*/
public function isAdmin()
{
return $this->type === 'admin';
}
/**
* Is the application a site one
*
* @return boolean
*/
public function isSite()
{
return $this->type === 'site';
}
/**
* Get type of application
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Is this an ajax query
*
* @return boolean
*/
public function isAjax()
{
if (DOING_AJAX === true) {
return true;
}
return false;
}
/**
* Get the ajax url
*
* @return mixed
*/
public function getAjaxUrl()
{
if ($this->isAdmin()) {
return admin_url('admin-ajax.php?action=' . $this->getName() . '&');
} else {
return admin_url('admin-ajax.php?juwpfisadmin=false&action=' . $this->getName() . '&');
}
}
/**
* Get the base url for the plugin
*
* @return mixed
*/
public function getBaseUrl()
{
return $this->url;
}
}

View File

@@ -0,0 +1,123 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Controller
*/
class Controller
{
/**
* Default controller task
*
* @var string
*/
public $default_task = 'display';
/**
* Render a view
*
* @return void
*/
public function display()
{
$view = $this->loadView();
$view->render();
}
/**
* Load view content
*
* @return mixed
*/
protected function loadView()
{
$viewname = Utilities::getInput('view');
if (empty($viewname)) {
$viewname = get_class($this);
$viewname = strtolower(str_replace(Factory::getApplication()->getName() . 'Controller', '', $viewname));
}
$viewname = preg_replace('/[^A-Z0-9_-]/i', '', $viewname);
$filepath = Factory::getApplication()->getPath() . DIRECTORY_SEPARATOR . Factory::getApplication()->getType() . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . $viewname . DIRECTORY_SEPARATOR;
if (file_exists($filepath . 'view.php')) {
require_once $filepath . 'view.php';
} else {
Error::raiseError('404', 'View file not found');
}
$class = Factory::getApplication()->getname() . 'View' . ucfirst($viewname);
$view = new $class();
$view->setPath($filepath);
return $view;
}
/**
* Get the model
*
* @param string $modelname Model name
*
* @return boolean
*/
public function getModel($modelname = null)
{
if (empty($modelname)) {
$modelname = get_class($this);
$modelname = str_replace(Factory::getApplication()->getName() . 'Controller', '', $modelname);
}
$modelname = preg_replace('/[^A-Z0-9_-]/i', '', $modelname);
$filepath = Factory::getApplication()->getPath() . DIRECTORY_SEPARATOR . Factory::getApplication()->getType() . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . strtolower($modelname) . '.php';
if (!file_exists($filepath)) {
return false;
}
include_once $filepath;
$class = Factory::getApplication()->getName() . 'Model' . $modelname;
$model = new $class();
return $model;
}
/**
* Redirect to an url
*
* @param string $location Location to redirect to
*
* @return void
*/
public function redirect($location)
{
if (!headers_sent()) {
wp_safe_redirect($location, 303);
} else {
echo '<script>document.location.href="' . esc_url($location, null, '') . '";</script>\n';
}
exit;
}
/**
* Exit a request serving a json result
*
* @param string $status Exit status
* @param array $datas Echoed datas
*
* @since 1.0.3
*
* @return void
*/
protected function exitStatus($status = '', $datas = array())
{
$response = array('response' => $status, 'datas' => $datas);
echo json_encode($response);
die();
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Document
*/
class Document
{
/**
* Document class instance
*
* @var Document
*/
protected static $instance;
/**
* Get Document instance
*
* @return Document
*/
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new Document();
}
return self::$instance;
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Error
*/
class Error
{
/**
* Raise an error
*
* @param string $type Error code
* @param string $message Error message
* @param string $title Error title
*
* @return void
*/
public static function raiseError($type = '404', $message = 'An error occurs', $title = 'Error')
{
wp_die(esc_html($message), esc_html($title), array('response' => esc_html($type)));
}
}

View File

@@ -0,0 +1,43 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Factory
*/
class Factory
{
/**
* Application reference
*
* @var Application
*/
protected static $application;
/**
* Document reference
*
* @var Document
*/
protected static $document;
/**
* Get application instance
*
* @return Application
*/
public static function getApplication()
{
return Application::getInstance();
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Field
*
* phpcs:disable WordPress.CSRF.NonceVerification -- Nonce verification is made in the Form::validate method
*/
class Field
{
/**
* Render <input> tag
*
* @param array $field Field to render
*
* @return string
*/
public function getfield($field)
{
$attributes = $field['@attributes'];
$html = '';
if (!empty($attributes['type']) || (!empty($attributes['hidden']) && $attributes['hidden'] !== 'true')) {
$html .= '<div class="control-group">';
if (!empty($attributes['label']) && $attributes['label'] !== '' && !empty($attributes['name']) && $attributes['name'] !== '') {
// phpcs:ignore WordPress.WP.I18n -- Allow non literal arg
$html .= '<label class="control-label" for="' . $attributes['name'] . '">' . __($attributes['label'], Factory::getApplication()->getName()) . '</label>';
}
$html .= '<div class="controls">';
}
if (empty($attributes['hidden']) || (!empty($attributes['hidden']) && $attributes['hidden'] !== 'true')) {
$html .= '<input';
} else {
$html .= '<hidden';
}
if (!empty($attributes)) {
foreach ($attributes as $attribute => $value) {
if (in_array($attribute, array('type', 'id', 'class', 'placeholder', 'name', 'value')) && isset($value)) {
$html .= ' ' . $attribute . '="' . $value . '"';
}
}
}
$html .= ' />';
if (!empty($attributes['help']) && $attributes['help'] !== '') {
$html .= '<p class="help-block">' . $attributes['help'] . '</p>';
}
if (!empty($attributes['type']) || (!empty($attributes['hidden']) && $attributes['hidden'] !== 'true')) {
$html .= '</div></div>';
}
return $html;
}
/**
* Validate a field content
*
* @param array $field Field content
*
* @return boolean|false|integer
*/
public function validate($field)
{
if (!empty($field['name'])) {
if (isset($_POST[$field['name']])) {
$value = $_POST[$field['name']];
} elseif (isset($_GET[$field['name']])) {
$value = $_GET[$field['name']];
}
}
if (!empty($field['required']) && $field['required'] === 'true') {
if (trim($value) === '') {
return false;
}
}
if (!isset($this->validate)) {
return true;
}
if (empty($value) && isset($field['required']) && $field['required'] === 'true') {
return false;
}
return preg_match($this->validate, $value);
}
/**
* Sanitize a field content
*
* @param array $field Field content
*
* @return mixed
*/
public function sanitize($field)
{
$value = null;
if (isset($_POST[$field['name']])) {
$value = $_POST[$field['name']];
} elseif (isset($_GET[$field['name']])) {
$value = $_GET[$field['name']];
}
return filter_var($value, FILTER_SANITIZE_STRING);
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
use Joomunited\WPFramework\v1_0_4\Factory;
defined('ABSPATH') || die();
/**
* Class Button
*/
class Button extends Field
{
/**
* Get the field
*
* @param array $field Field attributes
*
* @return string
*/
public function getfield($field)
{
$attributes = $field['@attributes'];
$html = '<div class="control-group">';
$html .= '<button';
$content = '';
if (!empty($attributes)) {
foreach ($attributes as $attribute => $value) {
if (in_array($attribute, array('id', 'class', 'name', 'value', 'type')) && !empty($value)) {
if ($attribute === 'value') {
$content = __($value, Factory::getApplication()->getName());
continue;
}
$html .= ' ' . $attribute . '="' . $value . '"';
}
}
}
$html .= '>' . $content . '</button>';
$html .= '</div>';
return $html;
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
use \Joomunited\WPFramework\v1_0_4\Application;
defined('ABSPATH') || die();
/**
* Class Checkbox
*/
class Checkbox extends Field
{
/**
* Get the field
*
* @param array $field Field attributes
*
* @return string
*/
public function getfield($field)
{
$attributes = $field['@attributes'];
$html = '';
if ($attributes['hidden'] !== 'true') {
$html .= '<div class="control-group">';
if (!empty($attributes['label']) && $attributes['label'] !== '' && !empty($attributes['name']) && $attributes['name'] !== '') {
$html .= '<label class="control-label" for="' . esc_attr($attributes['name']) . '">' . __($attributes['label'], Factory::getApplication()->getName()) . '</label>';
}
$html .= '<div class="controls">';
}
$cleanfield = $field;
unset($cleanfield['@attributes']);
if (!empty($cleanfield[0])) {
foreach ($cleanfield[0] as $child) {
if (!empty($child['option']['@attributes'])) {
$html .= '<input type="checkbox" ';
foreach ($child['option']['@attributes'] as $childAttribute => $childValue) {
if (in_array($childAttribute, array('id', 'class', 'name', 'onchange', 'value')) && isset($childValue)) {
$html .= ' ' . $childAttribute . '="' . $childValue . '"';
if ($childAttribute === 'value' && isset($attributes['value']) && $attributes['value'] === $childValue) {
$html .= ' selected="selected"';
}
}
}
$html .= '>';
$html .= __($child['option'][0], strtolower(Application::getInstance()->getName()));
$html .= '<br/>';
}
}
}
$html .= '</select>';
if (!empty($attributes['help']) && $attributes['help'] !== '') {
$html .= '<p class="help-block">' . $attributes['help'] . '</p>';
}
if (!empty($attributes['type']) && $attributes['hidden'] !== 'true') {
$html .= '</div></div>';
}
return $html;
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
defined('ABSPATH') || die();
/**
* Class Input
*/
class Input extends Field
{
/**
* Sanitize input value
*
* @param mixed $value Value to sanitize
*
* @return mixed
*/
public function sanitize($value)
{
return filter_var($value, FILTER_SANITIZE_STRING);
}
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
use Joomunited\WPFramework\v1_0_4\Factory;
use Joomunited\WPFramework\v1_0_4\Application;
defined('ABSPATH') || die();
/**
* Class Select
*/
class Select extends Field
{
/**
* Get the field
*
* @param array $field Field attributes
*
* @return string
*/
public function getfield($field)
{
$attributes = $field['@attributes'];
$html = '';
if (empty($attributes['hidden']) || (!empty($attributes['hidden']) && $attributes['hidden'] !== 'true')) {
$html .= '<div class="control-group">';
if (!empty($attributes['label']) && $attributes['label'] !== '' && !empty($attributes['name']) && $attributes['name'] !== '') {
$html .= '<label class="control-label" for="' . esc_attr($attributes['name']) . '">' . __($attributes['label'], Factory::getApplication()->getName()) . '</label>';
}
$html .= '<div class="controls">';
}
$html .= '<select';
if (!empty($attributes)) {
foreach ($attributes as $attribute => $value) {
if (in_array($attribute, array('id', 'class', 'onchange', 'name')) && isset($value)) {
$html .= ' ' . $attribute . '="' . $value . '"';
}
}
}
$html .= ' >';
$cleanfield = $field;
unset($cleanfield['@attributes']);
if (!empty($cleanfield[0])) {
foreach ($cleanfield[0] as $child) {
if (!empty($child['option']['@attributes'])) {
$html .= '<option ';
foreach ($child['option']['@attributes'] as $childAttribute => $childValue) {
if (in_array($childAttribute, array('type', 'id', 'class', 'name', 'onchange', 'value')) && isset($childValue)) {
$html .= ' ' . $childAttribute . '="' . $childValue . '"';
if ($childAttribute === 'value' && isset($attributes['value']) && $attributes['value'] === $childValue) {
$html .= ' selected="selected"';
}
}
}
$html .= '>';
$html .= __($child['option'][0], strtolower(Application::getInstance()->getName()));
$html .= '</option>';
}
}
}
$html .= '</select>';
if (!empty($attributes['help']) && $attributes['help'] !== '') {
$html .= '<p class="help-block">' . $attributes['help'] . '</p>';
}
if (!empty($attributes['type']) || (!empty($attributes['hidden']) && $attributes['hidden'] !== 'true')) {
$html .= '</div></div>';
}
return $html;
}
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
defined('ABSPATH') || die();
/**
* Class Submit
*/
class Submit extends Button
{
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
defined('ABSPATH') || die();
/**
* Class Text
*/
class Text extends Field
{
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
use Joomunited\WPFramework\v1_0_4\Factory;
defined('ABSPATH') || die();
/**
* Class Textarea
*/
class Textarea extends Field
{
/**
* Get the field
*
* @param array $field Field attributes
*
* @return string
*/
public function getfield($field)
{
$attributes = $field['@attributes'];
$html = '';
if (!empty($attributes['type']) || (!empty($attributes['hidden']) && $attributes['hidden'] !== 'true')) {
$html .= '<div class="control-group">';
if (!empty($attributes['label']) && $attributes['label'] !== '' && !empty($attributes['name']) && $attributes['name'] !== '') {
$html .= '<label class="control-label" for="' . esc_attr($attributes['name']) . '">' . __($attributes['label'], Factory::getApplication()->getName()) . '</label>';
}
$html .= '<div class="controls">';
}
$html .= '<textarea ';
if (!empty($attributes)) {
foreach ($attributes as $attribute => $value) {
if (in_array($attribute, array('id', 'class', 'placeholder', 'name', 'rows', 'cols')) && isset($value)) {
$html .= ' ' . $attribute . '="' . $value . '"';
}
}
}
$html .= ' >';
if (!empty($attributes['value'])) {
$html .= $attributes['value'];
}
$html .= ' </textarea>';
if (!empty($attributes['help']) && $attributes['help'] !== '') {
$html .= '<p class="help-block">' . $attributes['help'] . '</p>';
}
if (!empty($attributes['type']) || (!empty($attributes['hidden']) && $attributes['hidden'] !== 'true')) {
$html .= '</div></div>';
}
return $html;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4\Fields;
use Joomunited\WPFramework\v1_0_4\Field;
defined('ABSPATH') || die();
/**
* Class Typeint
* phpcs:disable WordPress.CSRF.NonceVerification -- Nonce verification is made in the Form::validate method
*/
class Typeint extends Field
{
/**
* Validation regex
*
* @var string
*/
protected $validate = '/[0-9]+/';
/**
* Get the field
*
* @param array $field Field attributes
*
* @return string
*/
public function getfield($field)
{
$attributes = &$field['@attributes'];
$attributes['value'] = (int)$attributes['value'];
$attributes['type'] = 'text';
return parent::getfield($field);
}
/**
* Sanitize a value
*
* @param array $field Field attributes to sanitize
*
* @return integer
*/
public function sanitize($field)
{
$value = null;
if (!empty($_POST[$field['name']])) {
$value = $_POST[$field['name']];
} elseif (!empty($_GET[$field['name']])) {
$value = $_GET[$field['name']];
}
return (int)$value;
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Filesystem
*/
class Filesystem
{
/**
* Remove recursively a directory
*
* @param string $directory Directory path to remove
*
* @return void
*/
public static function rmdir($directory)
{
foreach (glob('$directory/{,.}*', GLOB_BRACE) as $file) {
$filename = explode('/', $file);
$filename = $filename[count($filename) - 1];
if ($filename !== '.' && $filename !== '..') {
if (is_dir($file)) {
self::rmdir($file);
} else {
if (file_exists($file)) {
unlink($file);
}
}
}
}
if (file_exists($directory)) {
rmdir($directory);
}
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Filter
*/
class Filter
{
/**
* Get a model
*
* @param string $modelname Model name
*
* @return boolean
*/
public function getModel($modelname)
{
$modelname = preg_replace('/[^A-Z0-9_-]/i', '', $modelname);
$filepath = Factory::getApplication()->getPath() . DIRECTORY_SEPARATOR . Factory::getApplication()->getType() . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . strtolower($modelname) . '.php';
if (!file_exists($filepath)) {
return false;
}
include_once $filepath;
$class = Factory::getApplication()->getName() . 'Model' . $modelname;
$model = new $class();
return $model;
}
}

View File

@@ -0,0 +1,345 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
use Joomunited\WPFramework\v1_0_4\Fields;
defined('ABSPATH') || die();
/**
* HTML5 Form class with support of xml form config files
*/
class Form
{
/**
* Form attributes
*
* @var array
*/
public $form;
/**
* Final form generated content
*
* @var string
*/
private $content = '';
/**
* Form datas
*
* @var array|null
*/
private $datas = null;
/**
* List of errors
*
* @var array
*/
private $errors = array();
/**
* Nonce action
*
* @var string
*/
private $nonce_action = 'joomunited_save_form';
/**
* Nonce name
*
* @var string
*/
private $nonce_name = 'joomunited_nonce_field';
/**
* Load an xml form file
*
* @param string $form Xml file to load without path and extension
* @param array $datas Datas to pass to the forms
*
* @return boolean
*/
public function load($form, $datas = null)
{
$this->datas = $datas;
if (file_exists($form)) {
$file = $form;
} else {
$form = preg_replace('/[^A-Z0-9_-]/i', '', $form);
$file = Factory::getApplication()->getPath() . DIRECTORY_SEPARATOR . Factory::getApplication()->getType() . DIRECTORY_SEPARATOR . 'forms' . DIRECTORY_SEPARATOR . $form . '.xml';
}
if (!file_exists($file)) {
return false;
}
$xml_content = file_get_contents($file);
$sxi = new \SimpleXmlIterator($xml_content);
$this->form = self::loadChildrenRecusirve($sxi);
return true;
}
/**
* Load an xml object and convert it to recursive array
*
* @param \SimpleXMLIterator $sxi Iterator
* @param boolean $recursloop Recur
*
* @return mixed
*/
protected function loadChildrenRecusirve($sxi, $recursloop = false)
{
$a = array();
if ($recursloop === false) {
$a = (array)$sxi->attributes();
}
// phpcs:ignore Generic.CodeAnalysis.ForLoopWithTestFunctionCall -- Keep this for readability
for ($sxi->rewind(); $sxi->valid(); $sxi->next()) {
$acnt = (array)$sxi->current()->attributes();
if ($sxi->hasChildren()) {
$acnt[] = self::loadChildrenRecusirve($sxi->current(), true);
} else {
$val = strval($sxi->current());
if ($val) {
$acnt[] = strval($sxi->current());
}
}
$a[][$sxi->key()] = $acnt;
}
return $a;
}
/**
* Render a form to html
*
* @return string
*/
public function render()
{
$this->content = $this->start($this->form['@attributes']);
$this->content .= wp_nonce_field($this->nonce_action, $this->nonce_name, true, false);
$this->content .= $this->contentRender($this->form);
$this->content .= $this->close();
return $this->content;
}
/**
* Render the content of the form whitout the forms tags
*
* @param array $fields An array with the form fields
*
* @return string
*/
private function contentRender($fields)
{
$content = '';
foreach ($fields as $key => $value) {
if ($key !== '@attributes') {
$field = array_keys($value);
if ($field[0] === 'fieldset') {
$content .= $this->fieldset($value);
} else {
$content .= $this->input($value);
}
}
}
return $content;
}
/**
* Render an input type
*
* @param array $input Input array with the input to render
*
* @return string
*/
public function input($input)
{
$field = array_keys($input);
if (!empty($input[${'field'}[0]]['@attributes']['type'])) {
$class = ucfirst($input[${'field'}[0]]['@attributes']['type']);
} else {
$class = ucfirst($field[0]);
}
if (isset($this->datas) && !empty($input[${'field'}[0]]['@attributes']['name']) && isset($this->datas[$input[${'field'}[0]]['@attributes']['name']])) {
$input[${'field'}[0]]['@attributes']['value'] = $this->datas[$input[${'field'}[0]]['@attributes']['name']];
}
if (!empty($input[${'field'}[0]]['@attributes']['namespace'])) {
$class = $input[${'field'}[0]]['@attributes']['namespace'] . $class;
} else {
$class = '\Joomunited\WPFramework\v1_0_4\Fields\\' . $class;
}
if (class_exists($class, true)) {
$c = new $class;
return $c->getfield($input[$field[0]]);
}
return '';
}
/**
* Render a fieldset
*
* @param array $input Array with the input to render
*
* @return string
*/
public function fieldset($input)
{
$content = self::contentRender($input['fieldset']);
return $this->fieldsetField($input['fieldset']['@attributes'], $content);
}
/**
* Render <form> opening tag
* Attributes are action method id class enctype
*
* @param array $attributes List of form attributes
*
* @return string
*/
private function start(array $attributes = array())
{
$html = '<form';
if (!empty($attributes)) {
foreach ($attributes as $attribute => $value) {
if (in_array($attribute, array('action', 'method', 'id', 'class', 'enctype')) && !empty($value)) {
// assign default value to 'method' attribute
if ($attribute === 'method' && ($value !== 'post' || $value !== 'get')) {
$value = 'post';
}
$html .= ' ' . $attribute . '="' . $value . '"';
}
}
}
return $html . '>';
}
/**
* Render a fieldset field
*
* @param array $attributes The attributes of the fieldset
* @param string $contentbase The content of the fieldset
*
* @return string
*/
public static function fieldsetField(array $attributes, $contentbase)
{
$html = '<fieldset';
$content = '';
if (!empty($attributes)) {
foreach ($attributes as $attribute => $value) {
if (in_array($attribute, array('id', 'class', 'name', 'legend')) && !empty($value)) {
if ($attribute === 'legend') {
$content = '<legend>' . $value . '</legend>';
continue;
}
$html .= ' ' . $attribute . '="' . $value . '"';
}
}
}
return $html . '>' . $content . $contentbase . '</fieldset>';
}
/**
* Render </form> closing tag
*
* @return string
*/
public static function close()
{
return '</form>';
}
/**
* Validate form datas
*
* @return boolean
*/
public function validate()
{
if (empty($_REQUEST[$this->nonce_name]) || !wp_verify_nonce($_REQUEST[$this->nonce_name], $this->nonce_action)) {
return false;
}
foreach ($this->form as $key => $value) {
if ($key !== '@attributes') {
$field = array_keys($value);
if ($field !== 'fieldset') {
$field = array_keys($value);
if (!empty($value[${'field'}[0]]['@attributes']['type'])) {
$class = ucfirst($value[${'field'}[0]]['@attributes']['type']);
} else {
$class = ucfirst('Field' . $field[0]);
}
if (!empty($value[${'field'}[0]]['@attributes']['namespace'])) {
$class = $value[${'field'}[0]]['@attributes']['namespace'] . $class;
} else {
$class = '\Joomunited\WPFramework\v1_0_4\Fields\\' . $class;
}
if (class_exists($class)) {
$c = new $class;
if ($c->validate($value[$field[0]]['@attributes']) === false) {
$this->errors[] = $value[$field[0]]['@attributes']['name'];
}
}
}
}
}
if (!empty($this->errors)) {
return false;
}
return true;
}
/**
* Sanitize form datas
*
* @return array
*/
public function sanitize()
{
foreach ($this->form as $key => $value) {
if ($key !== '@attributes') {
$field = array_keys($value);
if (!empty($value[${'field'}[0]]['@attributes']['name'])) {
$field = array_keys($value);
if (!empty($value[${'field'}[0]]['@attributes']['type'])) {
$class = ucfirst($value[${'field'}[0]]['@attributes']['type']);
} else {
$class = ucfirst('Field' . $field[0]);
}
if (!empty($value[${'field'}[0]]['@attributes']['namespace'])) {
$class = $value[${'field'}[0]]['@attributes']['namespace'] . $class;
} else {
$class = '\Joomunited\WPFramework\v1_0_4\Fields\\' . $class;
}
if (class_exists($class)) {
$c = new $class;
$this->datas[$value[$field[0]]['@attributes']['name']] = $c->sanitize($value[$field[0]]['@attributes']);
}
}
}
}
return $this->datas;
}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Installer
*/
class Installer
{
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Model
*/
class Model
{
/**
* Database reference
*
* @var \wpdb
*/
protected $db;
/**
* Model constructor.
*/
public function __construct()
{
global $wpdb;
$this->db = &$wpdb;
}
/**
* Get class instance
*
* @param string $name Name of the model
* @param null $type Site or admin model
*
* @return boolean
*/
public static function getInstance($name = '', $type = null)
{
$app = Application::getInstance();
$name = preg_replace('/[^A-Z0-9_\.-]/i', '', $name);
if ($type === null) {
$type = $app->getType();
} elseif ($type !== 'admin' || $type !== 'site') {
return false;
}
$className = $app->getName() . 'Model' . ucfirst(strtolower($name));
$classFile = $app->getPath() . DIRECTORY_SEPARATOR . $type . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . strtolower($name) . '.php';
if (!file_exists($classFile)) {
return false;
}
require_once $classFile;
if (class_exists($className)) {
return new $className();
}
return false;
}
/**
* Get database prefix
*
* @return string
*/
public function getPrefix()
{
return $this->db->prefix;
}
/**
* Update a row in table
*
* @param string $table Table name
* @param array $data Datas to update
* @param array $where Where clause
* @param array|string $format An array of formats to be mapped to each of the values in $data.
* @param array|string $where_format An array of formats to be mapped to each of the values in $where.
*
* @return false|integer
*/
public function update($table, $data, $where, $format = null, $where_format = null)
{
return $this->db->update($table, $data, $where, $format, $where_format);
}
}

View File

@@ -0,0 +1,138 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class Utilities
*
* phpcs:disable WordPress.CSRF.NonceVerification -- Nonce verification is made in the Form::validate method
*/
class Utilities
{
/**
* Get a http variable
*
* @param string $name Name of the variable
* @param string $type Request type
* @param string $filter Type of filter to apply on the request
*
* @return null
*/
public static function getInput($name, $type = 'GET', $filter = 'cmd')
{
$input = null;
switch (strtoupper($type)) {
case 'GET':
if (isset($_GET[$name])) {
$input = $_GET[$name];
}
break;
case 'POST':
if (isset($_POST[$name])) {
$input = $_POST[$name];
}
break;
case 'FILES':
if (isset($_FILES[$name])) {
$input = $_FILES[$name];
}
break;
case 'COOKIE':
if (isset($_COOKIE[$name])) {
$input = $_COOKIE[$name];
}
break;
case 'ENV':
if (isset($_ENV[$name])) {
$input = $_ENV[$name];
}
break;
case 'SERVER':
if (isset($_SERVER[$name])) {
$input = $_SERVER[$name];
}
break;
default:
break;
}
switch (strtolower($filter)) {
case 'cmd':
$input = preg_replace('/[^a-z\.]+/', '', strtolower($input));
break;
case 'int':
$input = intval($input);
break;
case 'bool':
$input = $input ? 1 : 0;
break;
case 'string':
$input = sanitize_text_field($input);
break;
case 'none':
break;
default:
$input = null;
break;
}
return $input;
}
/**
* Get int from request variables
*
* @param string $name Request variable name
* @param string $type Request type
*
* @return null
*/
public static function getInt($name, $type = 'GET')
{
return self::getInput($name, $type, 'int');
}
/**
* Set an http variable
*
* @param string $name Request variable name
* @param string $value Request variable value
* @param string $type Request type
*
* @return void
*/
public static function setInput($name, $value, $type = 'GET')
{
switch (strtoupper($type)) {
case 'GET':
$_GET[$name] = $value;
break;
case 'POST':
$_POST[$name] = $value;
break;
case 'FILES':
$_FILES[$name] = $value;
break;
case 'COOKIE':
$_COOKIE[$name] = $value;
break;
case 'ENV':
$_ENV[$name] = $value;
break;
case 'SERVER':
$_SERVER[$name] = $value;
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**
* WP Framework
*
* @package WP File Download
* @author Joomunited
* @version 1.0
*/
namespace Joomunited\WPFramework\v1_0_4;
defined('ABSPATH') || die();
/**
* Class View
*/
class View
{
/**
* Default view template
*
* @var string
*/
public $default_tpl = 'default';
/**
* View path
*
* @var string
*/
protected $path;
/**
* Render a view
*
* @param string $tpl Template to render
*
* @return void
*/
public function render($tpl = null)
{
$result = $this->loadTemplate($tpl);
// phpcs:ignore WordPress.XSS.EscapeOutput -- Escaping should be done in the template itself
echo $result;
$pluginName = Application::getInstance()->getName();
if (defined(strtoupper($pluginName) . '_AJAX')) {
die();
}
}
/**
* Load a template file
*
* @param null $tpl Template file
*
* @return string
*/
public function loadTemplate($tpl = null)
{
$tpl = isset($tpl) ? $tpl : $this->default_tpl;
$file = preg_replace('/[^A-Z0-9_\.-]/i', '', $tpl);
$file = $this->path . 'tpl' . DIRECTORY_SEPARATOR . $file . '.php';
if (file_exists($file)) {
ob_start();
include $file;
$output = ob_get_contents();
ob_end_clean();
return $output;
}
return '';
}
/**
* Set path
*
* @param string $path Path
*
* @return void
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Retrieve model associated to the view
*
* @param string $modelname Model name
*
* @return Model|false
*/
public function getModel($modelname = null)
{
if (empty($modelname)) {
$modelname = get_class($this);
$modelname = str_replace(Factory::getApplication()->getName() . 'View', '', $modelname);
}
$modelname = preg_replace('/[^A-Z0-9_-]/i', '', $modelname);
$filepath = Factory::getApplication()->getPath() . DIRECTORY_SEPARATOR . Factory::getApplication()->getType() . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . strtolower($modelname) . '.php';
if (!file_exists($filepath)) {
return false;
}
include_once $filepath;
$class = Factory::getApplication()->getName() . 'Model' . ucfirst($modelname);
$model = new $class();
return $model;
}
}

View File

@@ -0,0 +1,232 @@
<?xml version="1.0"?>
<ruleset name="PHP_CodeSniffer">
<description>Joomunited coding standard for Wordpress plugins</description>
<file>.</file>
<arg name="basepath" value="."/>
<arg name="colors" />
<arg name="parallel" value="75" />
<arg name="extensions" value="php"/>
<!-- Define installed path of standards used -->
<config name="installed_paths" value="vendor/wimg/php-compatibility,vendor/wp-coding-standards/wpcs" />
<!-- Memory phpcs can you for this task -->
<ini name="memory_limit" value="200M"/>
<!--
#############################################################################
Exclude files we did not create
#############################################################################
-->
<exclude-pattern>vendor/*</exclude-pattern>
<!--
#############################################################################
Php compatibility check
#############################################################################
-->
<autoload>vendor/wimg/php-compatibility/PHPCSAliases.php</autoload>
<rule ref="PHPCompatibility"/>
<config name="testVersion" value="5.3-"/>
<!--
#############################################################################
Include the whole PSR2 standard
#############################################################################
-->
<rule ref="PSR2">
<!-- Excluded because of the defined('ABSPATH') check -->
<exclude name="PSR1.Files.SideEffects" />
<!-- Excluded because we don't have yet namespace in our plugins -->
<exclude name="PSR1.Classes.ClassDeclaration" />
<!-- Allow long line length -->
<exclude name="Generic.Files.LineLength" />
</rule>
<!--
#############################################################################
Our own coding style
#############################################################################
-->
<!-- Don't use double quotes -->
<rule ref="Squiz.Strings.DoubleQuoteUsage"/>
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar" />
<!-- Covers rule: Braces shall be used for all blocks. -->
<rule ref="Squiz.ControlStructures.ControlSignature"/>
<!-- Covers rule: Braces should always be used, even when they are not required. -->
<rule ref="Generic.ControlStructures.InlineControlStructure"/>
<!-- Covers rule: Never use shorthand PHP start tags. Always use full PHP tags. -->
<rule ref="Generic.PHP.DisallowShortOpenTag"/>
<rule ref="Generic.PHP.DisallowAlternativePHPTags"/>
<!-- Covers rule: Remove trailing whitespace at the end of each line of code. -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace"/>
<!-- Covers rule: Omitting the closing PHP tag at the end of a file is preferred. -->
<rule ref="PSR2.Files.ClosingTag"/>
<!-- Rule: In general, readability is more important than cleverness or brevity.
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/607 -->
<rule ref="Squiz.PHP.DisallowMultipleAssignments"/>
<rule ref="Generic.Formatting.DisallowMultipleStatements"/>
<!-- Rule: The goto statement must never be used. -->
<!-- Duplicate of upstream. Should defer to upstream version once minimum PHPCS requirement has gone up.
https://github.com/squizlabs/PHP_CodeSniffer/pull/1664 -->
<rule ref="WordPress.PHP.DiscourageGoto"/>
<rule ref="WordPress.PHP.DiscourageGoto.Found">
<type>error</type>
<message>The "goto" language construct should not be used.</message>
</rule>
<!-- Rule: The eval() construct is very dangerous, and is impossible to secure. ... these must not be used. -->
<rule ref="Squiz.PHP.Eval"/>
<rule ref="Squiz.PHP.Eval.Discouraged">
<type>error</type>
<message>eval() is a security risk so not allowed.</message>
</rule>
<!-- Don't use extract for readability and security -->
<rule ref="WordPress.Functions.DontExtract"/>
<!-- Do not use @ for silent errors -->
<rule ref="Generic.PHP.NoSilencedErrors"/>
<!-- Some general php rules -->
<rule ref="Generic.PHP.DeprecatedFunctions"/>
<rule ref="Generic.PHP.ForbiddenFunctions"/>
<rule ref="Generic.Functions.CallTimePassByReference"/>
<rule ref="Generic.CodeAnalysis.EmptyStatement"/>
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
<rule ref="Generic.Classes.DuplicateClassName"/>
<rule ref="Generic.Strings.UnnecessaryStringConcat">
<properties>
<property name="allowMultiline" value="true"/>
</properties>
</rule>
<!-- More generic PHP best practices.
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/607 -->
<rule ref="Squiz.PHP.NonExecutableCode"/>
<rule ref="Squiz.Operators.IncrementDecrementUsage"/>
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
<rule ref="Squiz.Functions.FunctionDuplicateArgument"/>
<!-- Encourage having only one class/interface/trait per file. -->
<!-- Once the minimum WPCS PHPCS requirement has gone up to PHPCS 3.1.0, these three sniffs can be
replaced by the more comprehensive Generic.Files.OneObjectStructurePerFile sniff. -->
<rule ref="Generic.Files.OneClassPerFile"/>
<rule ref="Generic.Files.OneClassPerFile.MultipleFound">
<type>warning</type>
<message>Best practice suggestion: Declare only one class in a file.</message>
</rule>
<rule ref="Generic.Files.OneInterfacePerFile"/>
<rule ref="Generic.Files.OneInterfacePerFile.MultipleFound">
<type>warning</type>
<message>Best practice suggestion: Declare only one interface in a file.</message>
</rule>
<rule ref="Generic.Files.OneTraitPerFile"/>
<rule ref="Generic.Files.OneTraitPerFile.MultipleFound">
<type>warning</type>
<message>Best practice suggestion: Declare only one trait in a file.</message>
</rule>
<!-- Warn against using fully-qualified class names instead of the self keyword. -->
<rule ref="Squiz.Classes.SelfMemberReference.NotUsed">
<!-- Restore default severity of 5 which WordPress-Core sets to 0. -->
<severity>5</severity>
</rule>
<!-- Check for PHP Parse errors.
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/522 -->
<rule ref="Generic.PHP.Syntax"/>
<!-- Phpdoc code commenting -->
<rule ref="Generic.Commenting.DocComment" />
<rule ref="Squiz.Commenting.FunctionComment">
<exclude name="Squiz.Commenting.FunctionComment.ParamCommentFullStop" />
<exclude name="Squiz.Commenting.FunctionComment.ThrowsNoFullStop" />
<exclude name="Squiz.Commenting.FunctionComment.ScalarTypeHintMissing" />
<exclude name="Squiz.Commenting.FunctionComment.TypeHintMissing" />
</rule>
<rule ref="Squiz.Commenting.ClassComment" />
<rule ref="Squiz.Commenting.VariableComment" />
<!--
#############################################################################
WordPress rules
#############################################################################
-->
<autoload>vendor/wp-coding-standards/wpcs/WordPress/PHPCSAliases.php</autoload>
<!-- Rule: in $wpdb->prepare - only %s and %d are used as placeholders. Note that they are not "quoted"! -->
<rule ref="WordPress.DB.PreparedSQLPlaceholders"/>
<!-- Covers rule: Escaping should be done as close to the time of the query as possible,
preferably by using $wpdb->prepare() -->
<rule ref="WordPress.WP.PreparedSQL"/>
<!-- Covers rule: Avoid touching the database directly. -->
<rule ref="WordPress.DB.RestrictedFunctions"/>
<rule ref="WordPress.DB.RestrictedClasses"/>
<!-- Check for correct usage of the WP i18n functions. -->
<rule ref="WordPress.WP.I18n">
<exclude name="WordPress.WP.I18n.NonSingularStringLiteralDomain" />
<exclude name="WordPress.WP.I18n.NonSingularStringLiteralText" />
</rule>
<!-- https://vip.wordpress.com/documentation/code-review-what-we-look-for/#validation-sanitization-and-escaping -->
<rule ref="WordPress.XSS.EscapeOutput"/>
<!-- Verify that a nonce check is done before using values in superglobals.
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/73 -->
<rule ref="WordPress.CSRF.NonceVerification"/>
<!-- Encourage the use of strict ( === and !== ) comparisons.
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/242 -->
<rule ref="WordPress.PHP.StrictComparisons"/>
<!-- https://vip.wordpress.com/documentation/code-review-what-we-look-for/#commented-out-code-debug-code-or-output -->
<rule ref="WordPress.PHP.DevelopmentFunctions"/>
<rule ref="WordPress.PHP.DevelopmentFunctions.error_log">
<type>error</type>
</rule>
<!-- https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#settings-alteration -->
<rule ref="WordPress.PHP.DevelopmentFunctions.prevent_path_disclosure">
<type>error</type>
</rule>
<!-- VIP recommends other functions -->
<rule ref="WordPress.WP.AlternativeFunctions.curl">
<message>Using cURL functions is highly discouraged within VIP context. Check (Fetching Remote Data) on VIP Documentation.</message>
</rule>
<rule ref="WordPress.WP.AlternativeFunctions.file_get_contents">
<message>%s() is highly discouraged, please use vip_safe_wp_remote_get() instead.</message>
<type>warning</type>
</rule>
<!-- Scripts & style should be enqueued.
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/35 -->
<rule ref="WordPress.WP.EnqueuedResources"/>
<!-- Warn against overriding WP global variables.
https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/26 -->
<rule ref="WordPress.Variables.GlobalVariables"/>
<!-- Verify that everything in the global namespace is prefixed. -->
<rule ref="WordPress.NamingConventions.PrefixAllGlobals"/>
</ruleset>