Merge branch 'develop' of github.com:Dolibarr/dolibarr into develop
This commit is contained in:
commit
cba0ef5693
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,6 +19,7 @@ Thumbs.db
|
|||||||
# Vagrant generated files
|
# Vagrant generated files
|
||||||
.vagrant
|
.vagrant
|
||||||
# Composer installed repositories
|
# Composer installed repositories
|
||||||
|
composer.lock
|
||||||
/htdocs/includes/**/.git
|
/htdocs/includes/**/.git
|
||||||
# Composer autoloader and unwanted files
|
# Composer autoloader and unwanted files
|
||||||
htdocs/includes/autoload.php
|
htdocs/includes/autoload.php
|
||||||
|
|||||||
@ -27,7 +27,7 @@ PHPExcel 1.8.1 LGPL-2.1+ Yes
|
|||||||
php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP
|
php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP
|
||||||
PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service
|
PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service
|
||||||
PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests
|
PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests
|
||||||
Restler 3.0 LGPL-3+ Yes Library to develop REST Web services
|
Restler 3.0.0RC6 LGPL-3+ Yes Library to develop REST Web services
|
||||||
TCPDF 6.2.12 LGPL-3+ Yes PDF generation
|
TCPDF 6.2.12 LGPL-3+ Yes PDF generation
|
||||||
TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement
|
TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement
|
||||||
Swift Mailer 5.4.2-DEV MIT license Yes Comprehensive mailing tools for PHP
|
Swift Mailer 5.4.2-DEV MIT license Yes Comprehensive mailing tools for PHP
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
"mike42/escpos-php": "dev-master",
|
"mike42/escpos-php": "dev-master",
|
||||||
"mobiledetect/mobiledetectlib": "2.8.17",
|
"mobiledetect/mobiledetectlib": "2.8.17",
|
||||||
"phpoffice/phpexcel": "1.8.1",
|
"phpoffice/phpexcel": "1.8.1",
|
||||||
"restler/framework": "^3.0",
|
"restler/framework": "3.0.0-RC6",
|
||||||
"tecnickcom/tcpdf": "6.2.12"
|
"tecnickcom/tcpdf": "6.2.12"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|||||||
420
composer.lock
generated
420
composer.lock
generated
@ -1,420 +0,0 @@
|
|||||||
{
|
|
||||||
"_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"
|
|
||||||
],
|
|
||||||
"hash": "c2b53c577364dbe3a56137043081b511",
|
|
||||||
"content-hash": "8f7a86cfbc13f45e13b73c49531818cb",
|
|
||||||
"packages": [
|
|
||||||
{
|
|
||||||
"name": "ccampbell/chromephp",
|
|
||||||
"version": "4.1.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/ccampbell/chromephp.git",
|
|
||||||
"reference": "c3c297615d48ae5b2a86a82311152d1ed095fcef"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/ccampbell/chromephp/zipball/c3c297615d48ae5b2a86a82311152d1ed095fcef",
|
|
||||||
"reference": "c3c297615d48ae5b2a86a82311152d1ed095fcef",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.0.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"ChromePhp": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"Apache-2.0"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Craig Campbell",
|
|
||||||
"email": "iamcraigcampbell@gmail.com",
|
|
||||||
"homepage": "http://craig.is",
|
|
||||||
"role": "Developer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Log variables to the Chrome console (via Chrome Logger Google Chrome extension).",
|
|
||||||
"homepage": "http://github.com/ccampbell/chromephp",
|
|
||||||
"keywords": [
|
|
||||||
"log",
|
|
||||||
"logging"
|
|
||||||
],
|
|
||||||
"time": "2013-06-26 03:44:33"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ckeditor/ckeditor",
|
|
||||||
"version": "dev-full/stable",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/ckeditor/ckeditor-releases.git",
|
|
||||||
"reference": "e3eb254641c4c349ffc19e49bd4a1a6831b5b6d0"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/e3eb254641c4c349ffc19e49bd4a1a6831b5b6d0",
|
|
||||||
"reference": "e3eb254641c4c349ffc19e49bd4a1a6831b5b6d0",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"GPL-2.0+",
|
|
||||||
"LGPL-2.1+",
|
|
||||||
"MPL-1.1+"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "CKSource",
|
|
||||||
"homepage": "http://cksource.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "JavaScript WYSIWYG web text editor.",
|
|
||||||
"homepage": "http://ckeditor.com",
|
|
||||||
"keywords": [
|
|
||||||
"CKEditor",
|
|
||||||
"editor",
|
|
||||||
"fckeditor",
|
|
||||||
"html",
|
|
||||||
"javascript",
|
|
||||||
"richtext",
|
|
||||||
"text",
|
|
||||||
"wysiwyg"
|
|
||||||
],
|
|
||||||
"time": "2016-03-31 16:19:25"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "mike42/escpos-php",
|
|
||||||
"version": "dev-master",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/mike42/escpos-php.git",
|
|
||||||
"reference": "96f05cbf460f5b67c2184ee4e91aedfbcedeb788"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/mike42/escpos-php/zipball/96f05cbf460f5b67c2184ee4e91aedfbcedeb788",
|
|
||||||
"reference": "96f05cbf460f5b67c2184ee4e91aedfbcedeb788",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "4.5.*"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Mike42\\": "src/Mike42"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Roni Saha",
|
|
||||||
"email": "roni.cse@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Michael Billington",
|
|
||||||
"email": "michael.billington@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Gergely Radics",
|
|
||||||
"email": "gerifield@ustream.tv"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Warren Doyle",
|
|
||||||
"email": "w.doyle@fuelled.co"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vharo",
|
|
||||||
"email": "vharo@geepok.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Thermal receipt printer library, for use with ESC/POS compatible printers",
|
|
||||||
"homepage": "https://github.com/mike42/escpos-php",
|
|
||||||
"keywords": [
|
|
||||||
"ESC-POS",
|
|
||||||
"driver",
|
|
||||||
"escpos",
|
|
||||||
"print",
|
|
||||||
"receipt"
|
|
||||||
],
|
|
||||||
"time": "2016-03-27 23:08:27"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "mobiledetect/mobiledetectlib",
|
|
||||||
"version": "2.8.17",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/serbanghita/Mobile-Detect.git",
|
|
||||||
"reference": "b87da5f63a76e9615a0c74fcf168657b1ea7e41d"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/b87da5f63a76e9615a0c74fcf168657b1ea7e41d",
|
|
||||||
"reference": "b87da5f63a76e9615a0c74fcf168657b1ea7e41d",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.0.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"codeclimate/php-test-reporter": "dev-master",
|
|
||||||
"johnkary/phpunit-speedtrap": "~1.0@dev",
|
|
||||||
"phpunit/phpunit": "*"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"classmap": [
|
|
||||||
"Mobile_Detect.php"
|
|
||||||
],
|
|
||||||
"psr-0": {
|
|
||||||
"Detection": "namespaced/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Serban Ghita",
|
|
||||||
"email": "serbanghita@gmail.com",
|
|
||||||
"homepage": "http://mobiledetect.net",
|
|
||||||
"role": "Developer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
|
|
||||||
"homepage": "https://github.com/serbanghita/Mobile-Detect",
|
|
||||||
"keywords": [
|
|
||||||
"detect mobile devices",
|
|
||||||
"mobile",
|
|
||||||
"mobile detect",
|
|
||||||
"mobile detector",
|
|
||||||
"php mobile detect"
|
|
||||||
],
|
|
||||||
"time": "2015-09-17 14:45:21"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "phpoffice/phpexcel",
|
|
||||||
"version": "1.8.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/PHPOffice/PHPExcel.git",
|
|
||||||
"reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/372c7cbb695a6f6f1e62649381aeaa37e7e70b32",
|
|
||||||
"reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-xml": "*",
|
|
||||||
"ext-xmlwriter": "*",
|
|
||||||
"php": ">=5.2.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"PHPExcel": "Classes/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"LGPL"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Maarten Balliauw",
|
|
||||||
"homepage": "http://blog.maartenballiauw.be"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Mark Baker"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Franck Lefevre",
|
|
||||||
"homepage": "http://blog.rootslabs.net"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Erik Tilt"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
|
||||||
"homepage": "http://phpexcel.codeplex.com",
|
|
||||||
"keywords": [
|
|
||||||
"OpenXML",
|
|
||||||
"excel",
|
|
||||||
"php",
|
|
||||||
"spreadsheet",
|
|
||||||
"xls",
|
|
||||||
"xlsx"
|
|
||||||
],
|
|
||||||
"time": "2015-05-01 07:00:55"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "restler/framework",
|
|
||||||
"version": "3.0.0",
|
|
||||||
"target-dir": "Luracast/Restler",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/Luracast/Restler-Framework.git",
|
|
||||||
"reference": "6ee10b3e5dbc6376916fed55ec2340a37cce436b"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/Luracast/Restler-Framework/zipball/6ee10b3e5dbc6376916fed55ec2340a37cce436b",
|
|
||||||
"reference": "6ee10b3e5dbc6376916fed55ec2340a37cce436b",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.0"
|
|
||||||
},
|
|
||||||
"replace": {
|
|
||||||
"luracast/restler": "3.*"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"bshaffer/oauth2-server-php": "v1.0",
|
|
||||||
"luracast/explorer": "*",
|
|
||||||
"mustache/mustache": "dev-master",
|
|
||||||
"rodneyrehm/plist": "dev-master",
|
|
||||||
"symfony/yaml": "*",
|
|
||||||
"twig/twig": "v1.13.0",
|
|
||||||
"zendframework/zendamf": "dev-master"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"bshaffer/oauth2-server-php": "Restler can provide OAuth2 authentication using this library (see require-dev for details)",
|
|
||||||
"luracast/explorer": "Restler's very own api explorer (see require-dev for details)",
|
|
||||||
"mustache/mustache": "Restler can render HtmlView using mustache/handlebar templates (see require-dev for details)",
|
|
||||||
"rodneyrehm/plist": "Restler supports tho Apple plist xml format (see require-dev for details)",
|
|
||||||
"symfony/yaml": "Restler can produce content in yaml format as well (see require-dev for details)",
|
|
||||||
"twig/twig": "Restler can render HtmlView using twig templates (see require-dev for details)",
|
|
||||||
"zendframework/zendamf": "Support for the amf document format (see require-dev for details)"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"master": "v3.0.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Luracast\\Restler": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"LGPL-2.1"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Luracast",
|
|
||||||
"email": "arul@luracast.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Nick nickl- Lombard",
|
|
||||||
"email": "github@jigsoft.co.za"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Just the Restler Framework without the tests and examples",
|
|
||||||
"homepage": "http://luracast.com/products/restler/",
|
|
||||||
"keywords": [
|
|
||||||
"api",
|
|
||||||
"framework",
|
|
||||||
"rest",
|
|
||||||
"server"
|
|
||||||
],
|
|
||||||
"time": "2015-08-04 07:52:49"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "tecnickcom/tcpdf",
|
|
||||||
"version": "6.2.12",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
|
||||||
"reference": "2f732eaa91b5665274689b1d40b285a7bacdc37f"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/2f732eaa91b5665274689b1d40b285a7bacdc37f",
|
|
||||||
"reference": "2f732eaa91b5665274689b1d40b285a7bacdc37f",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"classmap": [
|
|
||||||
"fonts",
|
|
||||||
"config",
|
|
||||||
"include",
|
|
||||||
"tcpdf.php",
|
|
||||||
"tcpdf_parser.php",
|
|
||||||
"tcpdf_import.php",
|
|
||||||
"tcpdf_barcodes_1d.php",
|
|
||||||
"tcpdf_barcodes_2d.php",
|
|
||||||
"include/tcpdf_colors.php",
|
|
||||||
"include/tcpdf_filters.php",
|
|
||||||
"include/tcpdf_font_data.php",
|
|
||||||
"include/tcpdf_fonts.php",
|
|
||||||
"include/tcpdf_images.php",
|
|
||||||
"include/tcpdf_static.php",
|
|
||||||
"include/barcodes/datamatrix.php",
|
|
||||||
"include/barcodes/pdf417.php",
|
|
||||||
"include/barcodes/qrcode.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"LGPLv3"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Nicola Asuni",
|
|
||||||
"email": "info@tecnick.com",
|
|
||||||
"homepage": "http://nicolaasuni.tecnick.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
|
|
||||||
"homepage": "http://www.tcpdf.org/",
|
|
||||||
"keywords": [
|
|
||||||
"PDFD32000-2008",
|
|
||||||
"TCPDF",
|
|
||||||
"barcodes",
|
|
||||||
"datamatrix",
|
|
||||||
"pdf",
|
|
||||||
"pdf417",
|
|
||||||
"qrcode"
|
|
||||||
],
|
|
||||||
"time": "2015-09-12 10:08:34"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"packages-dev": [],
|
|
||||||
"aliases": [],
|
|
||||||
"minimum-stability": "stable",
|
|
||||||
"stability-flags": {
|
|
||||||
"ckeditor/ckeditor": 20,
|
|
||||||
"mike42/escpos-php": 20
|
|
||||||
},
|
|
||||||
"prefer-stable": false,
|
|
||||||
"prefer-lowest": false,
|
|
||||||
"platform": {
|
|
||||||
"php": ">=5.3.0",
|
|
||||||
"ext-curl": "*"
|
|
||||||
},
|
|
||||||
"platform-dev": []
|
|
||||||
}
|
|
||||||
@ -49,6 +49,9 @@ $search_zip=GETPOST("search_zip");
|
|||||||
$search_town=GETPOST("search_town");
|
$search_town=GETPOST("search_town");
|
||||||
$search_state=GETPOST("search_state");
|
$search_state=GETPOST("search_state");
|
||||||
$search_country=GETPOST("search_country");
|
$search_country=GETPOST("search_country");
|
||||||
|
$search_phone=GETPOST("search_phone");
|
||||||
|
$search_phone_perso=GETPOST("search_phone_perso");
|
||||||
|
$search_phone_mobile=GETPOST("search_phone_mobile");
|
||||||
$type=GETPOST("type");
|
$type=GETPOST("type");
|
||||||
$search_email=GETPOST("search_email");
|
$search_email=GETPOST("search_email");
|
||||||
$search_categ = GETPOST("search_categ",'int');
|
$search_categ = GETPOST("search_categ",'int');
|
||||||
@ -104,6 +107,9 @@ $arrayfields=array(
|
|||||||
'd.address'=>array('label'=>$langs->trans("Address"), 'checked'=>0),
|
'd.address'=>array('label'=>$langs->trans("Address"), 'checked'=>0),
|
||||||
'd.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>0),
|
'd.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>0),
|
||||||
'd.town'=>array('label'=>$langs->trans("Town"), 'checked'=>0),
|
'd.town'=>array('label'=>$langs->trans("Town"), 'checked'=>0),
|
||||||
|
'd.phone'=>array('label'=>$langs->trans("Phone"), 'checked'=>0),
|
||||||
|
'd.phone_perso'=>array('label'=>$langs->trans("PhonePerso"), 'checked'=>0),
|
||||||
|
'd.phone_mobile'=>array('label'=>$langs->trans("PhoneMobile"), 'checked'=>0),
|
||||||
'state.nom'=>array('label'=>$langs->trans("State"), 'checked'=>0),
|
'state.nom'=>array('label'=>$langs->trans("State"), 'checked'=>0),
|
||||||
'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0),
|
'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0),
|
||||||
/*'d.note_public'=>array('label'=>$langs->trans("NotePublic"), 'checked'=>0),
|
/*'d.note_public'=>array('label'=>$langs->trans("NotePublic"), 'checked'=>0),
|
||||||
@ -151,6 +157,9 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP
|
|||||||
$search_town="";
|
$search_town="";
|
||||||
$search_state="";
|
$search_state="";
|
||||||
$search_country='';
|
$search_country='';
|
||||||
|
$search_phone='';
|
||||||
|
$search_phone_perso='';
|
||||||
|
$search_phone_mobile='';
|
||||||
$search_morphy="";
|
$search_morphy="";
|
||||||
$search_categ="";
|
$search_categ="";
|
||||||
$catid="";
|
$catid="";
|
||||||
@ -290,6 +299,9 @@ if ($resql)
|
|||||||
if ($search_zip != '') $param.= "&search_zip=".urlencode($search_zip);
|
if ($search_zip != '') $param.= "&search_zip=".urlencode($search_zip);
|
||||||
if ($search_state != '') $param.= "&search_state=".urlencode($search_state);
|
if ($search_state != '') $param.= "&search_state=".urlencode($search_state);
|
||||||
if ($search_country != '') $param.= "&search_country=".urlencode($search_country);
|
if ($search_country != '') $param.= "&search_country=".urlencode($search_country);
|
||||||
|
if ($search_phone != '') $param.= "&search_phone=".urlencode($search_phone);
|
||||||
|
if ($search_phone_perso != '') $param.= "&search_phone_perso=".urlencode($search_phone_perso);
|
||||||
|
if ($search_phone_mobile != '') $param.= "&search_phone_mobile=".urlencode($search_phone_mobile);
|
||||||
if ($filter) $param.="&filter=".urlencode($filter);
|
if ($filter) $param.="&filter=".urlencode($filter);
|
||||||
if ($type > 0) $param.="&type=".urlencode($type);
|
if ($type > 0) $param.="&type=".urlencode($type);
|
||||||
if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
|
if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
|
||||||
@ -347,7 +359,7 @@ if ($resql)
|
|||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
|
if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
|
||||||
{
|
{
|
||||||
print '<td width="5" align="center"> </td>';
|
print '<td colspan="1" align="center">'.$langs->trans("NumberingShort").'</td>';
|
||||||
}
|
}
|
||||||
if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],'d.rowid','',$param,'',$sortfield,$sortorder);
|
if (! empty($arrayfields['d.ref']['checked'])) print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],'d.rowid','',$param,'',$sortfield,$sortorder);
|
||||||
if (! empty($arrayfields['d.firstname']['checked'])) print_liste_field_titre($arrayfields['d.firstname']['label'],$_SERVER["PHP_SELF"],'d.firstname','',$param,'',$sortfield,$sortorder);
|
if (! empty($arrayfields['d.firstname']['checked'])) print_liste_field_titre($arrayfields['d.firstname']['label'],$_SERVER["PHP_SELF"],'d.firstname','',$param,'',$sortfield,$sortorder);
|
||||||
@ -361,6 +373,9 @@ if ($resql)
|
|||||||
if (! empty($arrayfields['d.town']['checked'])) print_liste_field_titre($arrayfields['d.town']['label'],$_SERVER["PHP_SELF"],'d.town','',$param,'',$sortfield,$sortorder);
|
if (! empty($arrayfields['d.town']['checked'])) print_liste_field_titre($arrayfields['d.town']['label'],$_SERVER["PHP_SELF"],'d.town','',$param,'',$sortfield,$sortorder);
|
||||||
if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($langs->trans("StateShort"),$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder);
|
if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($langs->trans("StateShort"),$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder);
|
||||||
if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($langs->trans("Country"),$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder);
|
if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($langs->trans("Country"),$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['d.phone']['checked'])) print_liste_field_titre($arrayfields['d.phone']['label'],$_SERVER["PHP_SELF"],'d.phone','',$param,'',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['d.phone_perso']['checked'])) print_liste_field_titre($arrayfields['d.phone_perso']['label'],$_SERVER["PHP_SELF"],'d.phone_perso','',$param,'',$sortfield,$sortorder);
|
||||||
|
if (! empty($arrayfields['d.phone_mobile']['checked'])) print_liste_field_titre($arrayfields['d.phone_mobile']['label'],$_SERVER["PHP_SELF"],'d.phone_mobile','',$param,'',$sortfield,$sortorder);
|
||||||
if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder);
|
if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder);
|
||||||
if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder);
|
if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder);
|
||||||
// Extra fields
|
// Extra fields
|
||||||
@ -388,6 +403,12 @@ if ($resql)
|
|||||||
// Line for filters fields
|
// Line for filters fields
|
||||||
print '<tr class="liste_titre">';
|
print '<tr class="liste_titre">';
|
||||||
|
|
||||||
|
// Line numbering
|
||||||
|
if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
|
||||||
|
{
|
||||||
|
print '<td class="liste_titre"> </td>';
|
||||||
|
}
|
||||||
|
|
||||||
// Ref
|
// Ref
|
||||||
if (! empty($arrayfields['d.ref']['checked']))
|
if (! empty($arrayfields['d.ref']['checked']))
|
||||||
{
|
{
|
||||||
@ -464,6 +485,24 @@ if ($resql)
|
|||||||
print $form->select_country($search_country,'search_country','',0,'maxwidth100');
|
print $form->select_country($search_country,'search_country','',0,'maxwidth100');
|
||||||
print '</td>';
|
print '</td>';
|
||||||
}
|
}
|
||||||
|
// Phone pro
|
||||||
|
if (! empty($arrayfields['d.phone']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="liste_titre" align="left">';
|
||||||
|
print '<input class="flat" type="text" name="search_phone" value="'.$search_phone.'" size="5"></td>';
|
||||||
|
}
|
||||||
|
// Phone perso
|
||||||
|
if (! empty($arrayfields['d.phone_perso']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="liste_titre" align="left">';
|
||||||
|
print '<input class="flat" type="text" name="search_phone_perso" value="'.$search_phone_perso.'" size="5"></td>';
|
||||||
|
}
|
||||||
|
// Phone mobile
|
||||||
|
if (! empty($arrayfields['d.phone_mobile']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="liste_titre" align="left">';
|
||||||
|
print '<input class="flat" type="text" name="search_phone_mobile" value="'.$search_phone_mobile.'" size="5"></td>';
|
||||||
|
}
|
||||||
// Email
|
// Email
|
||||||
if (! empty($arrayfields['d.email']['checked']))
|
if (! empty($arrayfields['d.email']['checked']))
|
||||||
{
|
{
|
||||||
@ -619,14 +658,6 @@ if ($resql)
|
|||||||
print $obj->address;
|
print $obj->address;
|
||||||
print '</td>';
|
print '</td>';
|
||||||
}
|
}
|
||||||
// Town
|
|
||||||
if (! empty($arrayfields['d.town']['checked']))
|
|
||||||
{
|
|
||||||
print '<td class="nocellnopadd">';
|
|
||||||
print $obj->town;
|
|
||||||
print '</td>';
|
|
||||||
if (! $i) $totalarray['nbfield']++;
|
|
||||||
}
|
|
||||||
// Zip
|
// Zip
|
||||||
if (! empty($arrayfields['d.zip']['checked']))
|
if (! empty($arrayfields['d.zip']['checked']))
|
||||||
{
|
{
|
||||||
@ -635,6 +666,14 @@ if ($resql)
|
|||||||
print '</td>';
|
print '</td>';
|
||||||
if (! $i) $totalarray['nbfield']++;
|
if (! $i) $totalarray['nbfield']++;
|
||||||
}
|
}
|
||||||
|
// Town
|
||||||
|
if (! empty($arrayfields['d.town']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="nocellnopadd">';
|
||||||
|
print $obj->town;
|
||||||
|
print '</td>';
|
||||||
|
if (! $i) $totalarray['nbfield']++;
|
||||||
|
}
|
||||||
// State
|
// State
|
||||||
if (! empty($arrayfields['state.nom']['checked']))
|
if (! empty($arrayfields['state.nom']['checked']))
|
||||||
{
|
{
|
||||||
@ -650,6 +689,30 @@ if ($resql)
|
|||||||
print '</td>';
|
print '</td>';
|
||||||
if (! $i) $totalarray['nbfield']++;
|
if (! $i) $totalarray['nbfield']++;
|
||||||
}
|
}
|
||||||
|
// Phone pro
|
||||||
|
if (! empty($arrayfields['d.phone']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="nocellnopadd">';
|
||||||
|
print $obj->phone;
|
||||||
|
print '</td>';
|
||||||
|
if (! $i) $totalarray['nbfield']++;
|
||||||
|
}
|
||||||
|
// Phone perso
|
||||||
|
if (! empty($arrayfields['d.phone_perso']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="nocellnopadd">';
|
||||||
|
print $obj->phone_perso;
|
||||||
|
print '</td>';
|
||||||
|
if (! $i) $totalarray['nbfield']++;
|
||||||
|
}
|
||||||
|
// Phone mobile
|
||||||
|
if (! empty($arrayfields['d.phone_mobile']['checked']))
|
||||||
|
{
|
||||||
|
print '<td class="nocellnopadd">';
|
||||||
|
print $obj->phone_mobile;
|
||||||
|
print '</td>';
|
||||||
|
if (! $i) $totalarray['nbfield']++;
|
||||||
|
}
|
||||||
// EMail
|
// EMail
|
||||||
if (! empty($arrayfields['d.email']['checked']))
|
if (! empty($arrayfields['d.email']['checked']))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -102,7 +102,7 @@ class Interfaces
|
|||||||
$nbfile++;
|
$nbfile++;
|
||||||
|
|
||||||
$modName = "Interface".ucfirst($reg[3]);
|
$modName = "Interface".ucfirst($reg[3]);
|
||||||
//print "file=$file"; print "modName=$modName"; exit;
|
//print "file=$file - modName=$modName\n";
|
||||||
if (in_array($modName,$modules))
|
if (in_array($modName,$modules))
|
||||||
{
|
{
|
||||||
$langs->load("errors");
|
$langs->load("errors");
|
||||||
@ -111,7 +111,15 @@ class Interfaces
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
//print 'Todo for '.$modName." : ".$newdir.'/'.$file."\n";
|
||||||
include_once $newdir.'/'.$file;
|
include_once $newdir.'/'.$file;
|
||||||
|
//print 'Done for '.$modName."\n";
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
dol_syslog('ko for '.$modName." ".$e->getMessage()."\n", LOG_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if trigger file is disabled by name
|
// Check if trigger file is disabled by name
|
||||||
|
|||||||
@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php';
|
|||||||
* @param int $type_user 0=Menu for backoffice, 1=Menu for front office
|
* @param int $type_user 0=Menu for backoffice, 1=Menu for front office
|
||||||
* @param array $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
* @param array $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||||
* @param array $menu Object Menu to return back list of menu entries
|
* @param array $menu Object Menu to return back list of menu entries
|
||||||
* @param int $noout Disable output (Initialise &$menu only).
|
* @param int $noout 1=Disable output (Initialise &$menu only).
|
||||||
* @return int 0
|
* @return int 0
|
||||||
*/
|
*/
|
||||||
function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0)
|
function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0)
|
||||||
@ -50,6 +50,19 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0)
|
|||||||
|
|
||||||
if (empty($noout)) print_start_menu_array();
|
if (empty($noout)) print_start_menu_array();
|
||||||
|
|
||||||
|
// Show/Hide vertical menu
|
||||||
|
if (GETPOST('testhidemenu') && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
|
||||||
|
{
|
||||||
|
$showmode=1;
|
||||||
|
$classname = 'class="tmenu"';
|
||||||
|
$idsel='home';
|
||||||
|
|
||||||
|
if (empty($noout)) print_start_menu_entry($idsel,$classname,$showmode);
|
||||||
|
if (empty($noout)) print_text_menu_entry($langs->trans("XXX"), 1, '#', $id, $idsel, $classname, $atarget);
|
||||||
|
if (empty($noout)) print_end_menu_entry($showmode);
|
||||||
|
$menu->add('#', $langs->trans("XXX"), 0, $showmode, $atarget, "xxx", '');
|
||||||
|
}
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
$showmode=1;
|
$showmode=1;
|
||||||
$classname="";
|
$classname="";
|
||||||
@ -463,7 +476,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
|
|||||||
print '</div>'."\n";
|
print '</div>'."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($moredata) && ! empty($moredata['searchform']))
|
if (is_array($moredata) && ! empty($moredata['searchform']) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
|
||||||
{
|
{
|
||||||
print "\n";
|
print "\n";
|
||||||
print "<!-- Begin SearchForm -->\n";
|
print "<!-- Begin SearchForm -->\n";
|
||||||
|
|||||||
@ -144,7 +144,7 @@ class MenuManager
|
|||||||
|
|
||||||
if ($mode == 'topnb')
|
if ($mode == 'topnb')
|
||||||
{
|
{
|
||||||
print_eldy_menu($this->db,$this->atarget,$this->type_user,$this->tabMenu,$this->menu,1);
|
print_eldy_menu($this->db,$this->atarget,$this->type_user,$this->tabMenu,$this->menu,1); // no output
|
||||||
return $this->menu->getNbOfVisibleMenuEntries();
|
return $this->menu->getNbOfVisibleMenuEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
17
htdocs/includes/pdfmake/pdfmake.min.js
vendored
17
htdocs/includes/pdfmake/pdfmake.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -13,7 +13,7 @@ use Luracast\Restler\iCache;
|
|||||||
* @copyright 2013 Luracast
|
* @copyright 2013 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class ApcCache implements iCache
|
class ApcCache implements iCache
|
||||||
{
|
{
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace Luracast\Restler {
|
|||||||
* @subpackage helper
|
* @subpackage helper
|
||||||
* @author Nick Lombard <github@jigsoft.co.za>
|
* @author Nick Lombard <github@jigsoft.co.za>
|
||||||
* @copyright 2012 Luracast
|
* @copyright 2012 Luracast
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class AutoLoader
|
class AutoLoader
|
||||||
{
|
{
|
||||||
@ -263,6 +263,12 @@ class AutoLoader
|
|||||||
* @return bool false unless className now exists
|
* @return bool false unless className now exists
|
||||||
*/
|
*/
|
||||||
private function loadLastResort($className, $loader = null) {
|
private function loadLastResort($className, $loader = null) {
|
||||||
|
// DOL_LDR Add protection to avoid conflict with other autouploader
|
||||||
|
/*print 'Try to load '.$className."\n";
|
||||||
|
if (in_array($className, array('Google_Client')))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
$loaders = array_unique(static::$rogueLoaders);
|
$loaders = array_unique(static::$rogueLoaders);
|
||||||
if (isset($loader)) {
|
if (isset($loader)) {
|
||||||
if (false === array_search($loader, $loaders))
|
if (false === array_search($loader, $loaders))
|
||||||
@ -301,8 +307,6 @@ class AutoLoader
|
|||||||
*/
|
*/
|
||||||
private function alias($className, $currentClass)
|
private function alias($className, $currentClass)
|
||||||
{
|
{
|
||||||
if ($className == 'Luracast\Restler\string') return;
|
|
||||||
if ($className == 'Luracast\Restler\mixed') return;
|
|
||||||
if ($className != $currentClass
|
if ($className != $currentClass
|
||||||
&& false !== strpos($className, $currentClass))
|
&& false !== strpos($className, $currentClass))
|
||||||
if (!class_exists($currentClass, false)
|
if (!class_exists($currentClass, false)
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
namespace Luracast\Restler;
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Luracast\Restler\Data\Text;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the PHPDoc comments for metadata. Inspired by `Documentor` code base.
|
* Parses the PHPDoc comments for metadata. Inspired by `Documentor` code base.
|
||||||
@ -13,7 +14,7 @@ use Exception;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class CommentParser
|
class CommentParser
|
||||||
{
|
{
|
||||||
@ -50,6 +51,15 @@ class CommentParser
|
|||||||
*/
|
*/
|
||||||
public static $arrayDelimiter = ',';
|
public static $arrayDelimiter = ',';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array annotations that support array value
|
||||||
|
*/
|
||||||
|
public static $allowsArrayValue = array(
|
||||||
|
'choice' => true,
|
||||||
|
'select' => true,
|
||||||
|
'properties' => true,
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* character sequence used to escape \@
|
* character sequence used to escape \@
|
||||||
*/
|
*/
|
||||||
@ -195,7 +205,7 @@ class CommentParser
|
|||||||
list(, $param, $value) = preg_split('/\@|\s/', $line, 3)
|
list(, $param, $value) = preg_split('/\@|\s/', $line, 3)
|
||||||
+ array('', '', '');
|
+ array('', '', '');
|
||||||
list($value, $embedded) = $this->parseEmbeddedData($value);
|
list($value, $embedded) = $this->parseEmbeddedData($value);
|
||||||
$value = array_filter(preg_split('/\s+/msu', $value));
|
$value = array_filter(preg_split('/\s+/msu', $value), 'strlen');
|
||||||
$this->parseParam($param, $value, $embedded);
|
$this->parseParam($param, $value, $embedded);
|
||||||
}
|
}
|
||||||
return $this->_data;
|
return $this->_data;
|
||||||
@ -214,6 +224,9 @@ class CommentParser
|
|||||||
$allowMultiple = false;
|
$allowMultiple = false;
|
||||||
switch ($param) {
|
switch ($param) {
|
||||||
case 'param' :
|
case 'param' :
|
||||||
|
case 'property' :
|
||||||
|
case 'property-read' :
|
||||||
|
case 'property-write' :
|
||||||
$value = $this->formatParam($value);
|
$value = $this->formatParam($value);
|
||||||
$allowMultiple = true;
|
$allowMultiple = true;
|
||||||
break;
|
break;
|
||||||
@ -280,9 +293,14 @@ class CommentParser
|
|||||||
$value[self::$embeddedDataName]
|
$value[self::$embeddedDataName]
|
||||||
+= $data[$param][self::$embeddedDataName];
|
+= $data[$param][self::$embeddedDataName];
|
||||||
}
|
}
|
||||||
|
if (!is_array($data[$param])) {
|
||||||
|
$data[$param] = array('description' => (string) $data[$param]);
|
||||||
|
}
|
||||||
|
if (is_array($value)) {
|
||||||
$data[$param] = $value + $data[$param];
|
$data[$param] = $value + $data[$param];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the inline php doc comments and embedded data.
|
* Parses the inline php doc comments and embedded data.
|
||||||
@ -303,14 +321,15 @@ class CommentParser
|
|||||||
}
|
}
|
||||||
while (preg_match('/{@(\w+)\s?([^}]*)}/ms', $subject, $matches)) {
|
while (preg_match('/{@(\w+)\s?([^}]*)}/ms', $subject, $matches)) {
|
||||||
$subject = str_replace($matches[0], '', $subject);
|
$subject = str_replace($matches[0], '', $subject);
|
||||||
if ($matches[2] == 'true' || $matches[2] == 'false') {
|
if ($matches[1] == 'pattern') {
|
||||||
|
throw new Exception('Inline pattern tag should follow {@pattern /REGEX_PATTERN_HERE/} format and can optionally include PCRE modifiers following the ending `/`');
|
||||||
|
} elseif (isset(static::$allowsArrayValue[$matches[1]])) {
|
||||||
|
$matches[2] = explode(static::$arrayDelimiter, $matches[2]);
|
||||||
|
} elseif ($matches[2] == 'true' || $matches[2] == 'false') {
|
||||||
$matches[2] = $matches[2] == 'true';
|
$matches[2] = $matches[2] == 'true';
|
||||||
} elseif ($matches[2] == '') {
|
} elseif ($matches[2] == '') {
|
||||||
$matches[2] = true;
|
$matches[2] = true;
|
||||||
}
|
} elseif ($matches[1] == 'required') {
|
||||||
if ($matches[1] == 'pattern') {
|
|
||||||
throw new Exception('Inline pattern tag should follow {@pattern /REGEX_PATTERN_HERE/} format and can optionally include PCRE modifiers following the ending `/`');
|
|
||||||
} elseif (false !== strpos($matches[2], static::$arrayDelimiter)) {
|
|
||||||
$matches[2] = explode(static::$arrayDelimiter, $matches[2]);
|
$matches[2] = explode(static::$arrayDelimiter, $matches[2]);
|
||||||
}
|
}
|
||||||
$data[$matches[1]] = $matches[2];
|
$data[$matches[1]] = $matches[2];
|
||||||
@ -376,12 +395,36 @@ class CommentParser
|
|||||||
|
|
||||||
private function formatThrows(array $value)
|
private function formatThrows(array $value)
|
||||||
{
|
{
|
||||||
$r = array();
|
$code = 500;
|
||||||
$r['code'] = count($value) && is_numeric($value[0])
|
$exception = 'Exception';
|
||||||
? intval(array_shift($value)) : 500;
|
if(count($value)>1){
|
||||||
$reason = implode(' ', $value);
|
$v1 = $value[0];
|
||||||
$r['reason'] = empty($reason) ? '' : $reason;
|
$v2 = $value[1];
|
||||||
return $r;
|
if(is_numeric($v1)){
|
||||||
|
$code = $v1;
|
||||||
|
$exception = $v2;
|
||||||
|
array_shift($value);
|
||||||
|
array_shift($value);
|
||||||
|
} elseif(is_numeric($v2)){
|
||||||
|
$code = $v2;
|
||||||
|
$exception = $v1;
|
||||||
|
array_shift($value);
|
||||||
|
array_shift($value);
|
||||||
|
} else {
|
||||||
|
$exception = $v1;
|
||||||
|
array_shift($value);
|
||||||
|
}
|
||||||
|
} elseif(count($value) && is_numeric($value[0])) {
|
||||||
|
$code = $value[0];
|
||||||
|
array_shift($value);
|
||||||
|
}
|
||||||
|
$message = implode(' ', $value);
|
||||||
|
if(!isset(RestException::$codes[$code])){
|
||||||
|
$code = 500;
|
||||||
|
} elseif(empty($message)){
|
||||||
|
$message = RestException::$codes[$code];
|
||||||
|
}
|
||||||
|
return compact('code','message','exception');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function formatClass(array $value)
|
private function formatClass(array $value)
|
||||||
@ -439,6 +482,10 @@ class CommentParser
|
|||||||
$r['name'] = substr($data, 1);
|
$r['name'] = substr($data, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isset($r['type']) && Text::endsWith($r['type'], '[]')) {
|
||||||
|
$r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2);
|
||||||
|
$r['type'] = 'array';
|
||||||
|
}
|
||||||
if ($value) {
|
if ($value) {
|
||||||
$r['description'] = implode(' ', $value);
|
$r['description'] = implode(' ', $value);
|
||||||
}
|
}
|
||||||
@ -458,6 +505,10 @@ class CommentParser
|
|||||||
$data = explode('|', $data);
|
$data = explode('|', $data);
|
||||||
$r['type'] = count($data) == 1 ? $data[0] : $data;
|
$r['type'] = count($data) == 1 ? $data[0] : $data;
|
||||||
}
|
}
|
||||||
|
if (isset($r['type']) && Text::endsWith($r['type'], '[]')) {
|
||||||
|
$r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2);
|
||||||
|
$r['type'] = 'array';
|
||||||
|
}
|
||||||
if ($value) {
|
if ($value) {
|
||||||
$r['description'] = implode(' ', $value);
|
$r['description'] = implode(' ', $value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Compose implements iCompose
|
class Compose implements iCompose
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Data;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class ApiMethodInfo extends ValueObject
|
class ApiMethodInfo extends ValueObject
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,6 +10,7 @@ namespace Luracast\Restler\Data;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Arr
|
class Arr
|
||||||
{
|
{
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use Exception;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Invalid extends Exception
|
class Invalid extends Exception
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Data;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Object
|
class Object
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,8 +10,9 @@ namespace Luracast\Restler\Data;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class String
|
class Text
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Given haystack contains the needle or not?
|
* Given haystack contains the needle or not?
|
||||||
@ -75,10 +76,21 @@ class String
|
|||||||
return
|
return
|
||||||
ucwords(
|
ucwords(
|
||||||
preg_replace(
|
preg_replace(
|
||||||
array('/(?<=[^A-Z])([A-Z])/', '/(?<=[^0-9])([0-9])/', '/(_)/'),
|
array('/(?<=[^A-Z])([A-Z])/', '/(?<=[^0-9])([0-9])/', '/([_-])/', '/[^a-zA-Z0-9\s]|\s\s+/'),
|
||||||
array(' $0', ' $0', ' '),
|
array(' $0', ' $0', ' ', ' '),
|
||||||
$name
|
$name
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert given string to be used as a slug or css class
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function slug($name)
|
||||||
|
{
|
||||||
|
return preg_replace('/[^a-zA-Z]+/', '-', strtolower(strip_tags($name)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ use Luracast\Restler\Util;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class ValidationInfo implements iValueObject
|
class ValidationInfo implements iValueObject
|
||||||
{
|
{
|
||||||
|
|||||||
@ -17,13 +17,24 @@ use Luracast\Restler\Util;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Validator implements iValidate
|
class Validator implements iValidate
|
||||||
{
|
{
|
||||||
public static $holdException = false;
|
public static $holdException = false;
|
||||||
public static $exceptions = array();
|
public static $exceptions = array();
|
||||||
|
|
||||||
|
public static $preFilters = array(
|
||||||
|
'*' => 'trim',
|
||||||
|
//'string' => 'strip_tags',
|
||||||
|
//'string' => 'htmlspecialchars',
|
||||||
|
//'int' => 'abs',
|
||||||
|
//'float' => 'abs',
|
||||||
|
//'CustomClass' => 'MyFilterClass::custom',
|
||||||
|
// please note that you wont get an instance
|
||||||
|
// of CustomClass. you will get an array instead
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate alphabetic characters.
|
* Validate alphabetic characters.
|
||||||
*
|
*
|
||||||
@ -116,6 +127,25 @@ class Validator implements iValidate
|
|||||||
throw new Invalid('Expecting only hexadecimal digits.');
|
throw new Invalid('Expecting only hexadecimal digits.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color specified as hexadecimals
|
||||||
|
*
|
||||||
|
* Check that given value contains only color.
|
||||||
|
*
|
||||||
|
* @param $input
|
||||||
|
* @param ValidationInfo|null $info
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws Invalid
|
||||||
|
*/
|
||||||
|
public static function color($input, ValidationInfo $info = null)
|
||||||
|
{
|
||||||
|
if (preg_match('/^#[a-f0-9]{6}$/i', $input)) {
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
throw new Invalid('Expecting color as hexadecimal digits.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate Telephone number
|
* Validate Telephone number
|
||||||
*
|
*
|
||||||
@ -360,6 +390,20 @@ class Validator implements iValidate
|
|||||||
{
|
{
|
||||||
$html = Scope::get('Restler')->responseFormat instanceof HtmlFormat;
|
$html = Scope::get('Restler')->responseFormat instanceof HtmlFormat;
|
||||||
$name = $html ? "<strong>$info->label</strong>" : "`$info->name`";
|
$name = $html ? "<strong>$info->label</strong>" : "`$info->name`";
|
||||||
|
if (
|
||||||
|
isset(static::$preFilters['*']) &&
|
||||||
|
is_scalar($input) &&
|
||||||
|
is_callable($func = static::$preFilters['*'])
|
||||||
|
) {
|
||||||
|
$input = $func($input);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
isset(static::$preFilters[$info->type]) &&
|
||||||
|
(is_scalar($input) || !empty($info->children)) &&
|
||||||
|
is_callable($func = static::$preFilters[$info->type])
|
||||||
|
) {
|
||||||
|
$input = $func($input);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (is_null($input)) {
|
if (is_null($input)) {
|
||||||
if ($info->required) {
|
if ($info->required) {
|
||||||
@ -470,6 +514,8 @@ class Validator implements iValidate
|
|||||||
return $r;
|
return $r;
|
||||||
|
|
||||||
case 'string' :
|
case 'string' :
|
||||||
|
case 'password' : //password fields with string
|
||||||
|
case 'search' : //search field with string
|
||||||
if (!is_string($input)) {
|
if (!is_string($input)) {
|
||||||
$error .= '. Expecting alpha numeric value';
|
$error .= '. Expecting alpha numeric value';
|
||||||
break;
|
break;
|
||||||
@ -602,13 +648,13 @@ class Validator implements iValidate
|
|||||||
}
|
}
|
||||||
foreach ($info->children as $key => $value) {
|
foreach ($info->children as $key => $value) {
|
||||||
$cv = new ValidationInfo($value);
|
$cv = new ValidationInfo($value);
|
||||||
|
$cv->name = "{$info->name}[$key]";
|
||||||
if (array_key_exists($key, $input) || $cv->required) {
|
if (array_key_exists($key, $input) || $cv->required) {
|
||||||
$instance->{$key} = static::validate(
|
$instance->{$key} = static::validate(
|
||||||
Util::nestedValue($input, $key),
|
Util::nestedValue($input, $key),
|
||||||
$cv
|
$cv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $instance;
|
return $instance;
|
||||||
@ -616,7 +662,7 @@ class Validator implements iValidate
|
|||||||
}
|
}
|
||||||
throw new RestException (400, $error);
|
throw new RestException (400, $error);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
static::$exceptions[] = $e;
|
static::$exceptions[$info->name] = $e;
|
||||||
if (static::$holdException) {
|
if (static::$holdException) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Data;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class ValueObject implements iValueObject
|
class ValueObject implements iValueObject
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace Luracast\Restler\Data;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iValidate {
|
interface iValidate {
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Data;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iValueObject
|
interface iValueObject
|
||||||
{
|
{
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use Luracast\Restler\Data\Validator;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Defaults
|
class Defaults
|
||||||
{
|
{
|
||||||
@ -166,6 +166,12 @@ class Defaults
|
|||||||
*/
|
*/
|
||||||
public static $emptyBodyForNullResponse = true;
|
public static $emptyBodyForNullResponse = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool when set to true, the response will not be outputted directly into the buffer.
|
||||||
|
* If set, Restler::handle() will return the response as a string.
|
||||||
|
*/
|
||||||
|
public static $returnResponse = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool enables CORS support
|
* @var bool enables CORS support
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
use Closure;
|
use Closure;
|
||||||
|
|
||||||
|
|||||||
582
htdocs/includes/restler/framework/Luracast/Restler/Explorer.php
Normal file
582
htdocs/includes/restler/framework/Luracast/Restler/Explorer.php
Normal file
@ -0,0 +1,582 @@
|
|||||||
|
<?php
|
||||||
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
|
use stdClass;
|
||||||
|
use Luracast\Restler\Data\Text;
|
||||||
|
use Luracast\Restler\Data\ValidationInfo;
|
||||||
|
use Luracast\Restler\Scope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Explorer
|
||||||
|
*
|
||||||
|
* @package Luracast\Restler
|
||||||
|
*
|
||||||
|
* @access hybrid
|
||||||
|
* @version 3.0.0rc6
|
||||||
|
*/
|
||||||
|
class Explorer implements iProvideMultiVersionApi
|
||||||
|
{
|
||||||
|
const SWAGGER_VERSION = '1.2';
|
||||||
|
/**
|
||||||
|
* @var bool should protected resources be shown to unauthenticated users?
|
||||||
|
*/
|
||||||
|
public static $hideProtected = true;
|
||||||
|
/**
|
||||||
|
* @var bool should we use format as extension?
|
||||||
|
*/
|
||||||
|
public static $useFormatAsExtension = true;
|
||||||
|
/*
|
||||||
|
* @var bool can we accept scalar values (string, int, float etc) as the request body?
|
||||||
|
*/
|
||||||
|
public static $allowScalarValueOnRequestBody = false;
|
||||||
|
/**
|
||||||
|
* @var array all http methods specified here will be excluded from
|
||||||
|
* documentation
|
||||||
|
*/
|
||||||
|
public static $excludedHttpMethods = array('OPTIONS');
|
||||||
|
/**
|
||||||
|
* @var array all paths beginning with any of the following will be excluded
|
||||||
|
* from documentation
|
||||||
|
*/
|
||||||
|
public static $excludedPaths = array();
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public static $placeFormatExtensionBeforeDynamicParts = true;
|
||||||
|
/**
|
||||||
|
* @var bool should we group all the operations with the same url or not
|
||||||
|
*/
|
||||||
|
public static $groupOperations = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string class that holds metadata as static properties
|
||||||
|
*/
|
||||||
|
public static $infoClass = 'Luracast\Restler\ExplorerInfo';
|
||||||
|
/**
|
||||||
|
* Injected at runtime
|
||||||
|
*
|
||||||
|
* @var Restler instance of restler
|
||||||
|
*/
|
||||||
|
public $restler;
|
||||||
|
/**
|
||||||
|
* @var string when format is not used as the extension this property is
|
||||||
|
* used to set the extension manually
|
||||||
|
*/
|
||||||
|
public $formatString = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array type mapping for converting data types to JSON-Schema Draft 4
|
||||||
|
* Which is followed by swagger 1.2 spec
|
||||||
|
*/
|
||||||
|
public static $dataTypeAlias = array(
|
||||||
|
//'string' => 'string',
|
||||||
|
'int' => 'integer',
|
||||||
|
'number' => 'number',
|
||||||
|
'float' => array('number', 'float'),
|
||||||
|
'bool' => 'boolean',
|
||||||
|
//'boolean' => 'boolean',
|
||||||
|
//'NULL' => 'null',
|
||||||
|
'array' => 'array',
|
||||||
|
//'object' => 'object',
|
||||||
|
'stdClass' => 'object',
|
||||||
|
'mixed' => 'string',
|
||||||
|
'date' => array('string', 'date'),
|
||||||
|
'datetime' => array('string', 'date-time'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array configurable symbols to differentiate public, hybrid and
|
||||||
|
* protected api
|
||||||
|
*/
|
||||||
|
public static $apiDescriptionSuffixSymbols = array(
|
||||||
|
0 => ' <i class="fa fa-lg fa-unlock-alt"></i>', //public api
|
||||||
|
1 => ' <i class="fa fa-lg fa-adjust"></i>', //hybrid api
|
||||||
|
2 => ' <i class="fa fa-lg fa-lock"></i>', //protected api
|
||||||
|
);
|
||||||
|
|
||||||
|
protected $models = array();
|
||||||
|
/**
|
||||||
|
* @var bool|stdClass
|
||||||
|
*/
|
||||||
|
protected $_fullDataRequested = false;
|
||||||
|
protected $crud = array(
|
||||||
|
'POST' => 'create',
|
||||||
|
'GET' => 'retrieve',
|
||||||
|
'PUT' => 'update',
|
||||||
|
'DELETE' => 'delete',
|
||||||
|
'PATCH' => 'partial update'
|
||||||
|
);
|
||||||
|
protected static $prefixes = array(
|
||||||
|
'get' => 'retrieve',
|
||||||
|
'index' => 'list',
|
||||||
|
'post' => 'create',
|
||||||
|
'put' => 'update',
|
||||||
|
'patch' => 'modify',
|
||||||
|
'delete' => 'remove',
|
||||||
|
);
|
||||||
|
protected $_authenticated = false;
|
||||||
|
protected $cacheName = '';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve static files for exploring
|
||||||
|
*
|
||||||
|
* Serves explorer html, css, and js files
|
||||||
|
*
|
||||||
|
* @url GET *
|
||||||
|
*/
|
||||||
|
public function get()
|
||||||
|
{
|
||||||
|
if (func_num_args() > 1 && func_get_arg(0) == 'resources') {
|
||||||
|
/**
|
||||||
|
* BUGFIX:
|
||||||
|
* If we use common resourcePath (e.g. $r->addAPIClass([api-class], 'api/shop')), than we must determine resource-ID of e.g. 'api/shop'!
|
||||||
|
*/
|
||||||
|
$arguments = func_get_args();
|
||||||
|
// remove first entry
|
||||||
|
array_shift($arguments);
|
||||||
|
// create ID
|
||||||
|
$id = implode('/', $arguments);
|
||||||
|
return $this->getResources($id);
|
||||||
|
}
|
||||||
|
$filename = implode('/', func_get_args());
|
||||||
|
$redirect = false;
|
||||||
|
if (
|
||||||
|
(empty($filename) && substr($_SERVER['REQUEST_URI'], -1, 1) != '/') ||
|
||||||
|
$filename == 'index.html'
|
||||||
|
) {
|
||||||
|
$status = 302;
|
||||||
|
$url = $this->restler->getBaseUrl() . '/' . $this->base() . '/';
|
||||||
|
header("{$_SERVER['SERVER_PROTOCOL']} $status " . RestException::$codes[$status]);
|
||||||
|
header("Location: $url");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
isset($this->restler->responseFormat) &&
|
||||||
|
$this->restler->responseFormat->getExtension() == 'js'
|
||||||
|
) {
|
||||||
|
$filename .= '.js';
|
||||||
|
}
|
||||||
|
PassThrough::file(__DIR__ . '/explorer/' . (empty($filename) ? 'index.html' : $filename), false, 0); //60 * 60 * 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resources()
|
||||||
|
{
|
||||||
|
$r = new stdClass();
|
||||||
|
$r->apiVersion = (string)$this->restler->getRequestedApiVersion();
|
||||||
|
$r->swaggerVersion = static::SWAGGER_VERSION;
|
||||||
|
$r->apis = $this->apis($r->apiVersion);
|
||||||
|
$r->authorizations = $this->authorizations();
|
||||||
|
$r->info = array_filter(get_class_vars(static::$infoClass));
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResources($id)
|
||||||
|
{
|
||||||
|
$r = new stdClass();
|
||||||
|
$r->apiVersion = (string)$this->restler->getRequestedApiVersion();
|
||||||
|
$r->swaggerVersion = static::SWAGGER_VERSION;
|
||||||
|
$r->basePath = $this->restler->getBaseUrl();
|
||||||
|
$r->resourcePath = "/$id";
|
||||||
|
|
||||||
|
$r->apis = $this->apis($r->apiVersion, $id);
|
||||||
|
$r->models = (object)$this->models;
|
||||||
|
|
||||||
|
$r->produces = $this->restler->getWritableMimeTypes();
|
||||||
|
$r->consumes = $this->restler->getReadableMimeTypes();
|
||||||
|
$r->authorizations = $this->authorizations();
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function apis($version = 1, $resource = false)
|
||||||
|
{
|
||||||
|
$map = Routes::findAll(static::$excludedPaths + array($this->base()), static::$excludedHttpMethods, $version);
|
||||||
|
$r = array();
|
||||||
|
$a = array();
|
||||||
|
foreach ($map as $path => $data) {
|
||||||
|
$route = $data[0]['route'];
|
||||||
|
$access = $data[0]['access'];
|
||||||
|
if ($access && !Text::contains($path, '{')) {
|
||||||
|
$r[] = array(
|
||||||
|
'path' => empty($path) ? '/root' : "/$path",
|
||||||
|
//'description' => ''
|
||||||
|
//TODO: Util::nestedValue($route, 'metadata', 'classDescription') ? : ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (static::$hideProtected && !$access)
|
||||||
|
continue;
|
||||||
|
$grouper = array();
|
||||||
|
foreach ($data as $item) {
|
||||||
|
$route = $item['route'];
|
||||||
|
$access = $item['access'];
|
||||||
|
if (static::$hideProtected && !$access)
|
||||||
|
continue;
|
||||||
|
$url = $route['url'];
|
||||||
|
if (isset($grouper[$url])) {
|
||||||
|
$grouper[$url]['operations'][] = $this->operation($route);
|
||||||
|
} else {
|
||||||
|
$api = array(
|
||||||
|
'path' => "/$url",
|
||||||
|
'description' =>
|
||||||
|
Util::nestedValue($route, 'metadata', 'classDescription') ? : '',
|
||||||
|
'operations' => array($this->operation($route))
|
||||||
|
);
|
||||||
|
static::$groupOperations
|
||||||
|
? $grouper[$url] = $api
|
||||||
|
: $a[$path][] = $api;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($grouper)) {
|
||||||
|
$a[$path] = array_values($grouper);
|
||||||
|
// sort REST-endpoints by path
|
||||||
|
foreach ($a as & $b) {
|
||||||
|
usort(
|
||||||
|
$b,
|
||||||
|
function ($x, $y) {
|
||||||
|
return $x['path'] > $y['path'];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$order = array(
|
||||||
|
'GET' => 1,
|
||||||
|
'POST' => 2,
|
||||||
|
'PUT' => 3,
|
||||||
|
'PATCH' => 4,
|
||||||
|
'DELETE' => 5
|
||||||
|
);
|
||||||
|
foreach ($a as & $b) {
|
||||||
|
usort(
|
||||||
|
$b,
|
||||||
|
function ($x, $y) use ($order) {
|
||||||
|
return
|
||||||
|
$x['operations'][0]->method ==
|
||||||
|
$y['operations'][0]->method
|
||||||
|
? $x['path'] > $y['path']
|
||||||
|
: $order[$x['operations'][0]->method] >
|
||||||
|
$order[$y['operations'][0]->method];
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (false !== $resource) {
|
||||||
|
if ($resource == 'root') $resource = '';
|
||||||
|
if (isset($a[$resource])) return $a[$resource];
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function operation($route)
|
||||||
|
{
|
||||||
|
$r = new stdClass();
|
||||||
|
$r->method = $route['httpMethod'];
|
||||||
|
$r->nickname = $this->nickname($route);
|
||||||
|
$r->parameters = $this->parameters($route);
|
||||||
|
|
||||||
|
$m = $route['metadata'];
|
||||||
|
|
||||||
|
$r->summary = isset($m['description'])
|
||||||
|
? $m['description']
|
||||||
|
: '';
|
||||||
|
$r->summary .= $route['accessLevel'] > 2
|
||||||
|
? static::$apiDescriptionSuffixSymbols[2]
|
||||||
|
: static::$apiDescriptionSuffixSymbols[$route['accessLevel']];
|
||||||
|
$r->notes = isset($m['longDescription'])
|
||||||
|
? $m['longDescription']
|
||||||
|
: '';
|
||||||
|
$r->responseMessages = $this->responseMessages($route);
|
||||||
|
$this->setType(
|
||||||
|
$r,
|
||||||
|
new ValidationInfo(Util::nestedValue($m, 'return') ? : array())
|
||||||
|
);
|
||||||
|
if (is_null($r->type) || 'mixed' == $r->type) {
|
||||||
|
$r->type = 'array';
|
||||||
|
} elseif ($r->type == 'null') {
|
||||||
|
$r->type = 'void';
|
||||||
|
} elseif (Text::contains($r->type, '|')) {
|
||||||
|
$r->type = 'array';
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: add $r->authorizations
|
||||||
|
//A list of authorizations required to execute this operation. While not mandatory, if used, it overrides
|
||||||
|
//the value given at the API Declaration's authorizations. In order to completely remove API Declaration's
|
||||||
|
//authorizations completely, an empty object ({}) may be applied.
|
||||||
|
//TODO: add $r->produces
|
||||||
|
//TODO: add $r->consumes
|
||||||
|
//A list of MIME types this operation can produce/consume. This is overrides the global produces definition at the root of the API Declaration. Each string value SHOULD represent a MIME type.
|
||||||
|
//TODO: add $r->deprecated
|
||||||
|
//Declares this operation to be deprecated. Usage of the declared operation should be refrained. Valid value MUST be either "true" or "false". Note: This field will change to type boolean in the future.
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parameters(array $route)
|
||||||
|
{
|
||||||
|
$r = array();
|
||||||
|
$children = array();
|
||||||
|
$required = false;
|
||||||
|
foreach ($route['metadata']['param'] as $param) {
|
||||||
|
$info = new ValidationInfo($param);
|
||||||
|
$description = isset($param['description']) ? $param['description'] : '';
|
||||||
|
if ('body' == $info->from) {
|
||||||
|
if ($info->required)
|
||||||
|
$required = true;
|
||||||
|
$param['description'] = $description;
|
||||||
|
$children[] = $param;
|
||||||
|
} else {
|
||||||
|
$r[] = $this->parameter($info, $description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($children)) {
|
||||||
|
if (
|
||||||
|
1 == count($children) &&
|
||||||
|
(static::$allowScalarValueOnRequestBody || !empty($children[0]['children']))
|
||||||
|
) {
|
||||||
|
$firstChild = $children[0];
|
||||||
|
if (empty($firstChild['children'])) {
|
||||||
|
$description = $firstChild['description'];
|
||||||
|
} else {
|
||||||
|
$description = '<section class="body-param">';
|
||||||
|
foreach ($firstChild['children'] as $child) {
|
||||||
|
$description .= isset($child['required']) && $child['required']
|
||||||
|
? '<strong>' . $child['name'] . '</strong> (required)<br/>'
|
||||||
|
: $child['name'] . '<br/>';
|
||||||
|
}
|
||||||
|
$description .= '</section>';
|
||||||
|
}
|
||||||
|
$r[] = $this->parameter(new ValidationInfo($firstChild), $description);
|
||||||
|
} else {
|
||||||
|
$description = '<section class="body-param">';
|
||||||
|
foreach ($children as $child) {
|
||||||
|
$description .= isset($child['required']) && $child['required']
|
||||||
|
? '<strong>' . $child['name'] . '</strong> (required)<br/>'
|
||||||
|
: $child['name'] . '<br/>';
|
||||||
|
}
|
||||||
|
$description .= '</section>';
|
||||||
|
|
||||||
|
//lets group all body parameters under a generated model name
|
||||||
|
$name = $this->nameModel($route);
|
||||||
|
$r[] = $this->parameter(
|
||||||
|
new ValidationInfo(array(
|
||||||
|
'name' => $name,
|
||||||
|
'type' => $name,
|
||||||
|
'from' => 'body',
|
||||||
|
'required' => $required,
|
||||||
|
'children' => $children
|
||||||
|
)),
|
||||||
|
$description
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parameter(ValidationInfo $info, $description = '')
|
||||||
|
{
|
||||||
|
$p = new stdClass();
|
||||||
|
if(isset($info->rules['model'])){
|
||||||
|
$info->type = $info->rules['model'];
|
||||||
|
}
|
||||||
|
$p->name = $info->name;
|
||||||
|
$this->setType($p, $info);
|
||||||
|
if (empty($info->children) || $info->type != 'array') {
|
||||||
|
//primitives
|
||||||
|
if ($info->default)
|
||||||
|
$p->defaultValue = $info->default;
|
||||||
|
if ($info->choice)
|
||||||
|
$p->enum = $info->choice;
|
||||||
|
if ($info->min)
|
||||||
|
$p->minimum = $info->min;
|
||||||
|
if ($info->max)
|
||||||
|
$p->maximum = $info->max;
|
||||||
|
//TODO: $p->items and $p->uniqueItems boolean
|
||||||
|
}
|
||||||
|
$p->description = $description;
|
||||||
|
$p->paramType = $info->from; //$info->from == 'body' ? 'form' : $info->from;
|
||||||
|
$p->required = $info->required;
|
||||||
|
$p->allowMultiple = false;
|
||||||
|
return $p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function responseMessages(array $route)
|
||||||
|
{
|
||||||
|
$r = array();
|
||||||
|
if (is_array($throws = Util::nestedValue($route, 'metadata', 'throws'))) {
|
||||||
|
foreach ($throws as $message) {
|
||||||
|
$m = (object)$message;
|
||||||
|
//TODO: add $m->responseModel from composer class
|
||||||
|
$r[] = $m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function model($type, array $children)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Bugfix:
|
||||||
|
* If we use namespaces, than the model will not be correct, if we use a short name for the type!
|
||||||
|
*
|
||||||
|
* Example (phpDoc/annotations in API-class, which uses custom domain-model with namespace):
|
||||||
|
* @param Car $car {@from body} {@type Aoe\RestServices\Domain\Model\Car}
|
||||||
|
* @return Car {@type Aoe\RestServices\Domain\Model\Car}
|
||||||
|
* Than, the model (in swagger-spec) must also be 'Aoe\RestServices\Domain\Model\Car' and not 'Car'
|
||||||
|
*
|
||||||
|
* When we use namespaces, than we must use the @type-annotation, otherwise the automatic reconstitution
|
||||||
|
* from request-data (e.g. when it is a POST-request) to custom domain-model-object will not work!
|
||||||
|
*
|
||||||
|
* Summary:
|
||||||
|
* - When we use no namespaces, than the type would not be changed, if we would call 'Util::getShortName'
|
||||||
|
* - When we use namespaces, than the model will not be correct, if we would call 'Util::getShortName'
|
||||||
|
* ...so this method-call is either needless or will create a bug/error
|
||||||
|
*/
|
||||||
|
//$type = Util::getShortName($type);
|
||||||
|
if (isset($this->models[$type]))
|
||||||
|
return $this->models[$type];
|
||||||
|
$r = new stdClass();
|
||||||
|
$r->id = $type;
|
||||||
|
$r->description = "$type Model"; //TODO: enhance this on Router
|
||||||
|
$r->required = array();
|
||||||
|
$r->properties = array();
|
||||||
|
foreach ($children as $child) {
|
||||||
|
$info = new ValidationInfo($child);
|
||||||
|
$p = new stdClass();
|
||||||
|
$this->setType($p, $info);
|
||||||
|
$p->description = isset($child['description']) ? $child['description'] : '';
|
||||||
|
if ($info->default)
|
||||||
|
$p->defaultValue = $info->default;
|
||||||
|
if ($info->choice)
|
||||||
|
$p->enum = $info->choice;
|
||||||
|
if ($info->min)
|
||||||
|
$p->minimum = $info->min;
|
||||||
|
if ($info->max)
|
||||||
|
$p->maximum = $info->max;
|
||||||
|
if ($info->required)
|
||||||
|
$r->required[] = $info->name;
|
||||||
|
$r->properties[$info->name] = $p;
|
||||||
|
}
|
||||||
|
//TODO: add $r->subTypes https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object
|
||||||
|
//TODO: add $r->discriminator https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object
|
||||||
|
$this->models[$type] = $r;
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setType(&$object, ValidationInfo $info)
|
||||||
|
{
|
||||||
|
//TODO: proper type management
|
||||||
|
if ($info->type == 'array') {
|
||||||
|
if ($info->children) {
|
||||||
|
$this->model($info->contentType, $info->children);
|
||||||
|
$object->items = (object)array(
|
||||||
|
'$ref' => $info->contentType
|
||||||
|
);
|
||||||
|
} elseif ($info->contentType && $info->contentType == 'associative') {
|
||||||
|
unset($info->contentType);
|
||||||
|
$this->model($info->type = 'Object', array(
|
||||||
|
array(
|
||||||
|
'name' => 'property',
|
||||||
|
'type' => 'string',
|
||||||
|
'default' => '',
|
||||||
|
'required' => false,
|
||||||
|
'description' => ''
|
||||||
|
)
|
||||||
|
));
|
||||||
|
} elseif ($info->contentType && $info->contentType != 'indexed') {
|
||||||
|
$object->items = (object)array(
|
||||||
|
'type' => $info->contentType
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$object->items = (object)array(
|
||||||
|
'type' => 'string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} elseif ($info->children) {
|
||||||
|
$this->model($info->type, $info->children);
|
||||||
|
} elseif (is_string($info->type) && $t = Util::nestedValue(static::$dataTypeAlias, strtolower($info->type))) {
|
||||||
|
if (is_array($t)) {
|
||||||
|
list($info->type, $object->format) = $t;
|
||||||
|
} else {
|
||||||
|
$info->type = $t;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$info->type = 'string';
|
||||||
|
}
|
||||||
|
$object->type = $info->type;
|
||||||
|
$has64bit = PHP_INT_MAX > 2147483647;
|
||||||
|
if ($object->type == 'integer') {
|
||||||
|
$object->format = $has64bit
|
||||||
|
? 'int64'
|
||||||
|
: 'int32';
|
||||||
|
} elseif ($object->type == 'number') {
|
||||||
|
$object->format = $has64bit
|
||||||
|
? 'double'
|
||||||
|
: 'float';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function nickname(array $route)
|
||||||
|
{
|
||||||
|
static $hash = array();
|
||||||
|
$method = $route['methodName'];
|
||||||
|
if (isset(static::$prefixes[$method])) {
|
||||||
|
$method = static::$prefixes[$method];
|
||||||
|
} else {
|
||||||
|
$method = str_replace(
|
||||||
|
array_keys(static::$prefixes),
|
||||||
|
array_values(static::$prefixes),
|
||||||
|
$method
|
||||||
|
);
|
||||||
|
}
|
||||||
|
while (isset($hash[$method]) && $route['url'] != $hash[$method]) {
|
||||||
|
//create another one
|
||||||
|
$method .= '_';
|
||||||
|
}
|
||||||
|
$hash[$method] = $route['url'];
|
||||||
|
return $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function nameModel(array $route)
|
||||||
|
{
|
||||||
|
static $hash = array();
|
||||||
|
$count = 1;
|
||||||
|
//$name = str_replace('/', '-', $route['url']) . 'Model';
|
||||||
|
$name = $route['className'] . 'Model';
|
||||||
|
while (isset($hash[$name . $count])) {
|
||||||
|
//create another one
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
$name .= $count;
|
||||||
|
$hash[$name] = $route['url'];
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function authorizations()
|
||||||
|
{
|
||||||
|
$r = new stdClass();
|
||||||
|
$r->apiKey = (object)array(
|
||||||
|
'type' => 'apiKey',
|
||||||
|
'passAs' => 'query',
|
||||||
|
'keyname' => 'api_key',
|
||||||
|
);
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function base()
|
||||||
|
{
|
||||||
|
return strtok($this->restler->url, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum api version supported by the api class
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function __getMaximumSupportedVersion()
|
||||||
|
{
|
||||||
|
return Scope::get('Restler')->getApiVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php namespace Luracast\Restler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ExplorerInfo
|
||||||
|
* @package Luracast\Restler
|
||||||
|
*
|
||||||
|
* @version 3.0.0rc6
|
||||||
|
*/
|
||||||
|
class ExplorerInfo
|
||||||
|
{
|
||||||
|
public static $title = 'Restler API Explorer';
|
||||||
|
public static $description = 'Live API Documentation';
|
||||||
|
public static $termsOfServiceUrl = null;
|
||||||
|
public static $contact = 'arul@luracast.com';
|
||||||
|
public static $license = 'LGPL-2.1';
|
||||||
|
public static $licenseUrl = 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html';
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@ use Luracast\Restler\RestException;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class RateLimit implements iFilter, iUseAuthentication
|
class RateLimit implements iFilter, iUseAuthentication
|
||||||
{
|
{
|
||||||
@ -53,7 +53,7 @@ class RateLimit implements iFilter, iUseAuthentication
|
|||||||
* @var array all paths beginning with any of the following will be excluded
|
* @var array all paths beginning with any of the following will be excluded
|
||||||
* from documentation
|
* from documentation
|
||||||
*/
|
*/
|
||||||
public static $excludedPaths = array('resources');
|
public static $excludedPaths = array('explorer');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
namespace Luracast\Restler;
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
use Luracast\Restler\Format\HtmlFormat;
|
use Luracast\Restler\Format\HtmlFormat;
|
||||||
|
use ArrayAccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storing and retrieving a message or array of key value pairs for one time use using $_SESSION
|
* Storing and retrieving a message or array of key value pairs for one time use using $_SESSION
|
||||||
@ -14,9 +15,9 @@ use Luracast\Restler\Format\HtmlFormat;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Flash //implements \JsonSerializable
|
class Flash implements ArrayAccess
|
||||||
{
|
{
|
||||||
const SUCCESS = 'success';
|
const SUCCESS = 'success';
|
||||||
const INFO = 'info';
|
const INFO = 'info';
|
||||||
@ -104,18 +105,22 @@ class Flash //implements \JsonSerializable
|
|||||||
*/
|
*/
|
||||||
public static function set(array $data)
|
public static function set(array $data)
|
||||||
{
|
{
|
||||||
if (!static::$instance)
|
if (!static::$instance) {
|
||||||
static::$instance = new Flash();
|
static::$instance = new Flash();
|
||||||
if (!isset($_SESSION['flash']))
|
}
|
||||||
|
if (!isset($_SESSION['flash'])) {
|
||||||
$_SESSION['flash'] = array();
|
$_SESSION['flash'] = array();
|
||||||
|
}
|
||||||
$_SESSION['flash'] += $data;
|
$_SESSION['flash'] += $data;
|
||||||
HtmlFormat::$data['flash'] = static::$instance;
|
HtmlFormat::$data['flash'] = static::$instance;
|
||||||
|
|
||||||
return static::$instance;
|
return static::$instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __get($name)
|
public function __get($name)
|
||||||
{
|
{
|
||||||
$this->usedOnce = true;
|
$this->usedOnce = true;
|
||||||
|
|
||||||
return Util::nestedValue($_SESSION, 'flash', $name);
|
return Util::nestedValue($_SESSION, 'flash', $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,9 +131,10 @@ class Flash //implements \JsonSerializable
|
|||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if ($this->usedOnce)
|
if ($this->usedOnce) {
|
||||||
unset($_SESSION['flash']);
|
unset($_SESSION['flash']);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify data which should be serialized to JSON
|
* Specify data which should be serialized to JSON
|
||||||
@ -139,8 +145,30 @@ class Flash //implements \JsonSerializable
|
|||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
$this->usedOnce = true;
|
$this->usedOnce = true;
|
||||||
|
|
||||||
return isset($_SESSION['flash'])
|
return isset($_SESSION['flash'])
|
||||||
? $_SESSION['flash']
|
? $_SESSION['flash']
|
||||||
: array();
|
: array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return $this->__isset($offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
return $this->__get($offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
//not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
//not implemented
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -17,13 +17,16 @@ use ZendAmf\Parser\OutputStream;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class AmfFormat extends Format
|
class AmfFormat extends DependentFormat
|
||||||
{
|
{
|
||||||
const MIME = 'application/x-amf';
|
const MIME = 'application/x-amf';
|
||||||
const EXTENSION = 'amf';
|
const EXTENSION = 'amf';
|
||||||
|
|
||||||
|
const PACKAGE_NAME = 'zendframework/zendamf:dev-master';
|
||||||
|
const EXTERNAL_CLASS = 'ZendAmf\\Parser\\Amf3\\Deserializer';
|
||||||
|
|
||||||
public function encode($data, $humanReadable = false)
|
public function encode($data, $humanReadable = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use Luracast\Restler\RestException;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class CsvFormat extends Format implements iDecodeStream
|
class CsvFormat extends Format implements iDecodeStream
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
namespace Luracast\Restler\Format;
|
||||||
|
|
||||||
|
|
||||||
|
use Luracast\Restler\RestException;
|
||||||
|
|
||||||
|
abstract class DependentFormat extends Format
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* override in the extending class
|
||||||
|
*
|
||||||
|
* @example symfony/yaml:*
|
||||||
|
*/
|
||||||
|
const PACKAGE_NAME = 'vendor/project:version';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* override in the extending class
|
||||||
|
*
|
||||||
|
* fully qualified class name
|
||||||
|
*/
|
||||||
|
const EXTERNAL_CLASS = 'Namespace\\ClassName';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get external class => packagist package name as an associative array
|
||||||
|
*
|
||||||
|
* @return array list of dependencies for the format
|
||||||
|
*/
|
||||||
|
public function getDependencyMap()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
static::EXTERNAL_CLASS => static::PACKAGE_NAME
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkDependency($class = null)
|
||||||
|
{
|
||||||
|
if (empty($class)) {
|
||||||
|
$class = key($this->getDependencyMap());
|
||||||
|
}
|
||||||
|
if (!class_exists($class, true)) {
|
||||||
|
$map = $this->getDependencyMap();
|
||||||
|
$package = $map[$class];
|
||||||
|
throw new RestException(
|
||||||
|
500,
|
||||||
|
get_called_class() . ' has external dependency. Please run `composer require ' .
|
||||||
|
$package . '` from the project root. Read https://getcomposer.org for more info'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->checkDependency();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
namespace Luracast\Restler\Format;
|
||||||
|
|
||||||
|
|
||||||
|
use Luracast\Restler\RestException;
|
||||||
|
|
||||||
|
abstract class DependentMultiFormat extends MultiFormat
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get external class => packagist package name as an associative array
|
||||||
|
*
|
||||||
|
* @return array list of dependencies for the format
|
||||||
|
*
|
||||||
|
* @example return ['Illuminate\\View\\View' => 'illuminate/view:4.2.*']
|
||||||
|
*/
|
||||||
|
abstract public function getDependencyMap();
|
||||||
|
|
||||||
|
protected function checkDependency($class = null)
|
||||||
|
{
|
||||||
|
if (empty($class)) {
|
||||||
|
$class = key($this->getDependencyMap());
|
||||||
|
}
|
||||||
|
if (!class_exists($class, true)) {
|
||||||
|
$map = $this->getDependencyMap();
|
||||||
|
$package = $map[$class];
|
||||||
|
throw new RestException(
|
||||||
|
500,
|
||||||
|
get_called_class() . ' has external dependency. Please run `composer require ' .
|
||||||
|
$package . '` from the project root. Read https://getcomposer.org for more info'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->checkDependency();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -10,7 +10,7 @@ namespace Luracast\Restler\Format;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
abstract class Format implements iFormat
|
abstract class Format implements iFormat
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,11 +6,11 @@ use Illuminate\Events\Dispatcher;
|
|||||||
use Illuminate\Filesystem\Filesystem;
|
use Illuminate\Filesystem\Filesystem;
|
||||||
use Illuminate\View\Compilers\BladeCompiler;
|
use Illuminate\View\Compilers\BladeCompiler;
|
||||||
use Illuminate\View\Engines\CompilerEngine;
|
use Illuminate\View\Engines\CompilerEngine;
|
||||||
|
use Illuminate\View\Engines\PhpEngine;
|
||||||
use Illuminate\View\Engines\EngineResolver;
|
use Illuminate\View\Engines\EngineResolver;
|
||||||
use Illuminate\View\Factory;
|
use Illuminate\View\Factory;
|
||||||
use Illuminate\View\FileViewFinder;
|
use Illuminate\View\FileViewFinder;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use Luracast\Restler\Data\ApiMethodInfo;
|
|
||||||
use Luracast\Restler\Data\Object;
|
use Luracast\Restler\Data\Object;
|
||||||
use Luracast\Restler\Defaults;
|
use Luracast\Restler\Defaults;
|
||||||
use Luracast\Restler\RestException;
|
use Luracast\Restler\RestException;
|
||||||
@ -29,9 +29,9 @@ use Luracast\Restler\Util;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class HtmlFormat extends Format
|
class HtmlFormat extends DependentFormat
|
||||||
{
|
{
|
||||||
public static $mime = 'text/html';
|
public static $mime = 'text/html';
|
||||||
public static $extension = 'html';
|
public static $extension = 'html';
|
||||||
@ -39,6 +39,7 @@ class HtmlFormat extends Format
|
|||||||
public static $errorView = 'debug.php';
|
public static $errorView = 'debug.php';
|
||||||
public static $template = 'php';
|
public static $template = 'php';
|
||||||
public static $handleSession = true;
|
public static $handleSession = true;
|
||||||
|
public static $convertResponseToArray = false;
|
||||||
|
|
||||||
public static $useSmartViews = true;
|
public static $useSmartViews = true;
|
||||||
/**
|
/**
|
||||||
@ -83,11 +84,16 @@ class HtmlFormat extends Format
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDependencyMap(){
|
||||||
|
return array(
|
||||||
|
'Illuminate\View\View' => 'illuminate/view:4.2.*',
|
||||||
|
'Twig_Environment' => 'twig/twig:v1.13.*',
|
||||||
|
'Mustache_Engine' => 'mustache/mustache:dev-master',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static function blade(array $data, $debug = true)
|
public static function blade(array $data, $debug = true)
|
||||||
{
|
{
|
||||||
if (!class_exists('\Illuminate\View\View', true))
|
|
||||||
throw new RestException(500,
|
|
||||||
'Blade templates require laravel view classes to be installed using `composer install`');
|
|
||||||
$resolver = new EngineResolver();
|
$resolver = new EngineResolver();
|
||||||
$files = new Filesystem();
|
$files = new Filesystem();
|
||||||
$compiler = new BladeCompiler($files, static::$cacheDirectory);
|
$compiler = new BladeCompiler($files, static::$cacheDirectory);
|
||||||
@ -95,6 +101,10 @@ class HtmlFormat extends Format
|
|||||||
$resolver->register('blade', function () use ($engine) {
|
$resolver->register('blade', function () use ($engine) {
|
||||||
return $engine;
|
return $engine;
|
||||||
});
|
});
|
||||||
|
$phpEngine = new PhpEngine();
|
||||||
|
$resolver->register('php', function () use ($phpEngine) {
|
||||||
|
return $phpEngine;
|
||||||
|
});
|
||||||
|
|
||||||
/** @var Restler $restler */
|
/** @var Restler $restler */
|
||||||
$restler = Scope::get('Restler');
|
$restler = Scope::get('Restler');
|
||||||
@ -120,9 +130,6 @@ class HtmlFormat extends Format
|
|||||||
|
|
||||||
public static function twig(array $data, $debug = true)
|
public static function twig(array $data, $debug = true)
|
||||||
{
|
{
|
||||||
if (!class_exists('\Twig_Environment', true))
|
|
||||||
throw new RestException(500,
|
|
||||||
'Twig templates require twig classes to be installed using `composer install`');
|
|
||||||
$loader = new \Twig_Loader_Filesystem(static::$viewPath);
|
$loader = new \Twig_Loader_Filesystem(static::$viewPath);
|
||||||
$twig = new \Twig_Environment($loader, array(
|
$twig = new \Twig_Environment($loader, array(
|
||||||
'cache' => static::$cacheDirectory,
|
'cache' => static::$cacheDirectory,
|
||||||
@ -176,12 +183,6 @@ class HtmlFormat extends Format
|
|||||||
|
|
||||||
public static function mustache(array $data, $debug = true)
|
public static function mustache(array $data, $debug = true)
|
||||||
{
|
{
|
||||||
if (!class_exists('\Mustache_Engine', true))
|
|
||||||
throw new RestException(
|
|
||||||
500,
|
|
||||||
'Mustache/Handlebar templates require mustache classes ' .
|
|
||||||
'to be installed using `composer install`'
|
|
||||||
);
|
|
||||||
if (!isset($data['nav']))
|
if (!isset($data['nav']))
|
||||||
$data['nav'] = array_values(Nav::get());
|
$data['nav'] = array_values(Nav::get());
|
||||||
$options = array(
|
$options = array(
|
||||||
@ -313,7 +314,9 @@ class HtmlFormat extends Format
|
|||||||
$success = is_null($exception);
|
$success = is_null($exception);
|
||||||
$error = $success ? null : $exception->getMessage();
|
$error = $success ? null : $exception->getMessage();
|
||||||
$data = array(
|
$data = array(
|
||||||
'response' => Object::toArray($data),
|
'response' => static::$convertResponseToArray
|
||||||
|
? Object::toArray($data)
|
||||||
|
: $data,
|
||||||
'stages' => $this->restler->getEvents(),
|
'stages' => $this->restler->getEvents(),
|
||||||
'success' => $success,
|
'success' => $success,
|
||||||
'error' => $error
|
'error' => $error
|
||||||
@ -334,10 +337,7 @@ class HtmlFormat extends Format
|
|||||||
self::$view = $metadata[$view];
|
self::$view = $metadata[$view];
|
||||||
}
|
}
|
||||||
} elseif (!self::$view) {
|
} elseif (!self::$view) {
|
||||||
$file = static::$viewPath . '/' . $this->restler->url . '.' . static::getViewExtension();
|
self::$view = static::guessViewName($this->restler->url);
|
||||||
self::$view = static::$useSmartViews && is_readable($file)
|
|
||||||
? $this->restler->url
|
|
||||||
: static::$errorView;
|
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
isset($metadata['param'])
|
isset($metadata['param'])
|
||||||
@ -368,12 +368,19 @@ class HtmlFormat extends Format
|
|||||||
if (!static::$cacheDirectory) {
|
if (!static::$cacheDirectory) {
|
||||||
static::$cacheDirectory = Defaults::$cacheDirectory . DIRECTORY_SEPARATOR . $template;
|
static::$cacheDirectory = Defaults::$cacheDirectory . DIRECTORY_SEPARATOR . $template;
|
||||||
if (!file_exists(static::$cacheDirectory)) {
|
if (!file_exists(static::$cacheDirectory)) {
|
||||||
if (!mkdir(static::$cacheDirectory)) {
|
if (!mkdir(static::$cacheDirectory, 0770, true)) {
|
||||||
throw new RestException(500, 'Unable to create cache directory `' . static::$cacheDirectory . '`');
|
throw new RestException(500, 'Unable to create cache directory `' . static::$cacheDirectory . '`');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (method_exists($class = get_called_class(), $template)) {
|
if (method_exists($class = get_called_class(), $template)) {
|
||||||
|
if ($template == 'blade') {
|
||||||
|
$this->checkDependency('Illuminate\View\View');
|
||||||
|
} elseif ($template == 'twig') {
|
||||||
|
$this->checkDependency('Twig_Environment');
|
||||||
|
} elseif ($template == 'mustache' || $template == 'handlebar') {
|
||||||
|
$this->checkDependency('Mustache_Engine');
|
||||||
|
}
|
||||||
return call_user_func("$class::$template", $data, $humanReadable);
|
return call_user_func("$class::$template", $data, $humanReadable);
|
||||||
}
|
}
|
||||||
throw new RestException(500, "Unsupported template system `$template`");
|
throw new RestException(500, "Unsupported template system `$template`");
|
||||||
@ -384,6 +391,20 @@ class HtmlFormat extends Format
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function guessViewName($path)
|
||||||
|
{
|
||||||
|
if (empty($path)) {
|
||||||
|
$path = 'index';
|
||||||
|
} elseif (strpos($path, '/')) {
|
||||||
|
$path .= '/index';
|
||||||
|
}
|
||||||
|
$file = static::$viewPath . '/' . $path . '.' . static::getViewExtension();
|
||||||
|
|
||||||
|
return static::$useSmartViews && is_readable($file)
|
||||||
|
? $path
|
||||||
|
: static::$errorView;
|
||||||
|
}
|
||||||
|
|
||||||
public static function getViewExtension()
|
public static function getViewExtension()
|
||||||
{
|
{
|
||||||
return isset(static::$customTemplateExtensions[static::$template])
|
return isset(static::$customTemplateExtensions[static::$template])
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Format;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class JsFormat extends JsonFormat
|
class JsFormat extends JsonFormat
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,7 +14,7 @@ use Luracast\Restler\RestException;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class JsonFormat extends Format
|
class JsonFormat extends Format
|
||||||
{
|
{
|
||||||
@ -57,37 +57,60 @@ class JsonFormat extends Format
|
|||||||
if (is_null(self::$unEscapedUnicode)) {
|
if (is_null(self::$unEscapedUnicode)) {
|
||||||
self::$unEscapedUnicode = $this->charset == 'utf-8';
|
self::$unEscapedUnicode = $this->charset == 'utf-8';
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = 0;
|
$options = 0;
|
||||||
|
|
||||||
if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) // PHP >= 5.4
|
if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) // PHP >= 5.4
|
||||||
|| PHP_MAJOR_VERSION > 5 // PHP >= 6.0
|
|| PHP_MAJOR_VERSION > 5 // PHP >= 6.0
|
||||||
) {
|
) {
|
||||||
if ($humanReadable) $options |= JSON_PRETTY_PRINT;
|
|
||||||
if (self::$unEscapedSlashes) $options |= JSON_UNESCAPED_SLASHES;
|
if ($humanReadable) {
|
||||||
if (self::$bigIntAsString) $options |= JSON_BIGINT_AS_STRING;
|
$options |= JSON_PRETTY_PRINT;
|
||||||
if (self::$unEscapedUnicode) $options |= JSON_UNESCAPED_UNICODE;
|
}
|
||||||
return json_encode(
|
|
||||||
Object::toArray($data, true), $options
|
if (self::$unEscapedSlashes) {
|
||||||
);
|
$options |= JSON_UNESCAPED_SLASHES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::$bigIntAsString) {
|
||||||
|
$options |= JSON_BIGINT_AS_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::$unEscapedUnicode) {
|
||||||
|
$options |= JSON_UNESCAPED_UNICODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = json_encode(Object::toArray($data, true), $options);
|
||||||
|
$this->handleJsonError();
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = json_encode(Object::toArray($data, true));
|
$result = json_encode(Object::toArray($data, true));
|
||||||
if ($humanReadable) $result = $this->formatJson($result);
|
$this->handleJsonError();
|
||||||
|
|
||||||
|
if ($humanReadable) {
|
||||||
|
$result = $this->formatJson($result);
|
||||||
|
}
|
||||||
|
|
||||||
if (self::$unEscapedUnicode) {
|
if (self::$unEscapedUnicode) {
|
||||||
$result = preg_replace_callback('/\\\u(\w\w\w\w)/',
|
$result = preg_replace_callback(
|
||||||
function($matches)
|
'/\\\u(\w\w\w\w)/',
|
||||||
{
|
function ($matches) {
|
||||||
if (function_exists('mb_convert_encoding'))
|
if (function_exists('mb_convert_encoding')) {
|
||||||
{
|
|
||||||
return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UTF-16BE');
|
return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UTF-16BE');
|
||||||
|
} else {
|
||||||
|
return iconv('UTF-16BE', 'UTF-8', pack('H*', $matches[1]));
|
||||||
}
|
}
|
||||||
else
|
},
|
||||||
{
|
$result
|
||||||
return iconv('UTF-16BE','UTF-8',pack('H*', $matches[1]));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self::$unEscapedSlashes) {
|
||||||
|
$result = str_replace('\/', '/', $result);
|
||||||
}
|
}
|
||||||
, $result);
|
|
||||||
}
|
|
||||||
if (self::$unEscapedSlashes) $result = str_replace('\/', '/', $result);
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,39 +125,21 @@ class JsonFormat extends Format
|
|||||||
} else {
|
} else {
|
||||||
$data = preg_replace(
|
$data = preg_replace(
|
||||||
'/:\s*(\-?\d+(\.\d+)?([e|E][\-|\+]\d+)?)/',
|
'/:\s*(\-?\d+(\.\d+)?([e|E][\-|\+]\d+)?)/',
|
||||||
': "$1"', $data
|
': "$1"',
|
||||||
|
$data
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$decoded = json_decode($data, $options);
|
$decoded = json_decode($data, $options);
|
||||||
if (function_exists('json_last_error')) {
|
$this->handleJsonError();
|
||||||
switch (json_last_error()) {
|
} catch (\RuntimeException $e) {
|
||||||
case JSON_ERROR_NONE :
|
throw new RestException(400, $e->getMessage());
|
||||||
return Object::toArray($decoded);
|
|
||||||
break;
|
|
||||||
case JSON_ERROR_DEPTH :
|
|
||||||
$message = 'maximum stack depth exceeded';
|
|
||||||
break;
|
|
||||||
case JSON_ERROR_STATE_MISMATCH :
|
|
||||||
$message = 'underflow or the modes mismatch';
|
|
||||||
break;
|
|
||||||
case JSON_ERROR_CTRL_CHAR :
|
|
||||||
$message = 'unexpected control character found';
|
|
||||||
break;
|
|
||||||
case JSON_ERROR_SYNTAX :
|
|
||||||
$message = 'malformed JSON';
|
|
||||||
break;
|
|
||||||
case JSON_ERROR_UTF8 :
|
|
||||||
$message = 'malformed UTF-8 characters, possibly ' .
|
|
||||||
'incorrectly encoded';
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
$message = 'unknown error';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
throw new RestException (400, 'Error parsing JSON, ' . $message);
|
|
||||||
} elseif (strlen($data) && $decoded === null || $decoded === $data) {
|
if (strlen($data) && $decoded === null || $decoded === $data) {
|
||||||
throw new RestException (400, 'Error parsing JSON');
|
throw new RestException(400, 'Error parsing JSON');
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object::toArray($decoded);
|
return Object::toArray($decoded);
|
||||||
@ -206,5 +211,52 @@ class JsonFormat extends Format
|
|||||||
|
|
||||||
return $newJson;
|
return $newJson;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception if an error occurred during the last JSON encoding/decoding
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
protected function handleJsonError()
|
||||||
|
{
|
||||||
|
if (function_exists('json_last_error_msg') && json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
|
||||||
|
// PHP >= 5.5.0
|
||||||
|
|
||||||
|
$message = json_last_error_msg();
|
||||||
|
|
||||||
|
} elseif (function_exists('json_last_error')) {
|
||||||
|
|
||||||
|
// PHP >= 5.3.0
|
||||||
|
|
||||||
|
switch (json_last_error()) {
|
||||||
|
case JSON_ERROR_NONE:
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_DEPTH:
|
||||||
|
$message = 'maximum stack depth exceeded';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_STATE_MISMATCH:
|
||||||
|
$message = 'underflow or the modes mismatch';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_CTRL_CHAR:
|
||||||
|
$message = 'unexpected control character found';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_SYNTAX:
|
||||||
|
$message = 'malformed JSON';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_UTF8:
|
||||||
|
$message = 'malformed UTF-8 characters, possibly ' .
|
||||||
|
'incorrectly encoded';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$message = 'unknown error';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($message)) {
|
||||||
|
throw new \RuntimeException('Error encoding/decoding JSON: '. $message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,7 +9,7 @@ namespace Luracast\Restler\Format;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
abstract class MultiFormat implements iFormat
|
abstract class MultiFormat implements iFormat
|
||||||
{
|
{
|
||||||
|
|||||||
@ -18,9 +18,9 @@ use CFPropertyList\CFPropertyList;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class PlistFormat extends MultiFormat
|
class PlistFormat extends DependentMultiFormat
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var boolean set it to true binary plist is preferred
|
* @var boolean set it to true binary plist is preferred
|
||||||
@ -81,11 +81,24 @@ class PlistFormat extends MultiFormat
|
|||||||
*/
|
*/
|
||||||
public function decode($data)
|
public function decode($data)
|
||||||
{
|
{
|
||||||
//require_once 'CFPropertyList.php';
|
|
||||||
$plist = new CFPropertyList ();
|
$plist = new CFPropertyList ();
|
||||||
$plist->parse($data);
|
$plist->parse($data);
|
||||||
|
|
||||||
return $plist->toArray();
|
return $plist->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get external class => packagist package name as an associative array
|
||||||
|
*
|
||||||
|
* @return array list of dependencies for the format
|
||||||
|
*
|
||||||
|
* @example return ['Illuminate\\View\\View' => 'illuminate/view:4.2.*']
|
||||||
|
*/
|
||||||
|
public function getDependencyMap()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'CFPropertyList\CFPropertyList' => 'rodneyrehm/plist:dev-master'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Format;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class TsvFormat extends CsvFormat
|
class TsvFormat extends CsvFormat
|
||||||
{
|
{
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use Luracast\Restler\RestException;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class UploadFormat extends Format
|
class UploadFormat extends Format
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Format;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class UrlEncodedFormat extends Format
|
class UrlEncodedFormat extends Format
|
||||||
{
|
{
|
||||||
|
|||||||
@ -16,7 +16,7 @@ use XMLWriter;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class XmlFormat extends Format
|
class XmlFormat extends Format
|
||||||
{
|
{
|
||||||
@ -110,14 +110,16 @@ class XmlFormat extends Format
|
|||||||
foreach (static::$namespaces as $prefix => $ns) {
|
foreach (static::$namespaces as $prefix => $ns) {
|
||||||
if (isset(static::$namespacedProperties[static::$rootName])
|
if (isset(static::$namespacedProperties[static::$rootName])
|
||||||
&& static::$namespacedProperties[static::$rootName] == $prefix
|
&& static::$namespacedProperties[static::$rootName] == $prefix
|
||||||
)
|
) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
$prefix = 'xmlns' . (empty($prefix) ? '' : ':' . $prefix);
|
$prefix = 'xmlns' . (empty($prefix) ? '' : ':' . $prefix);
|
||||||
$xml->writeAttribute($prefix, $ns);
|
$xml->writeAttribute($prefix, $ns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->write($xml, $data, static::$rootName);
|
$this->write($xml, $data, static::$rootName);
|
||||||
$xml->endElement();
|
$xml->endElement();
|
||||||
|
|
||||||
return $xml->outputMemory();
|
return $xml->outputMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,20 +153,6 @@ class XmlFormat extends Format
|
|||||||
&& !empty(static::$namespacedProperties[$key])
|
&& !empty(static::$namespacedProperties[$key])
|
||||||
&& false === strpos($key, ':');
|
&& false === strpos($key, ':');
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
if ($value == array_values($value)) {
|
|
||||||
//numeric array, create siblings
|
|
||||||
foreach ($value as $v) {
|
|
||||||
$useNS
|
|
||||||
? $xml->startElementNs(
|
|
||||||
static::$namespacedProperties[$key],
|
|
||||||
$key,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
: $xml->startElement($key);
|
|
||||||
$this->write($xml, $v, $key);
|
|
||||||
$xml->endElement();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$useNS
|
$useNS
|
||||||
? $xml->startElementNs(
|
? $xml->startElementNs(
|
||||||
static::$namespacedProperties[$key],
|
static::$namespacedProperties[$key],
|
||||||
@ -174,7 +162,6 @@ class XmlFormat extends Format
|
|||||||
: $xml->startElement($key);
|
: $xml->startElement($key);
|
||||||
$this->write($xml, $value, $key);
|
$this->write($xml, $value, $key);
|
||||||
$xml->endElement();
|
$xml->endElement();
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
} elseif (is_bool($value)) {
|
} elseif (is_bool($value)) {
|
||||||
$value = $value ? 'true' : 'false';
|
$value = $value ? 'true' : 'false';
|
||||||
@ -217,6 +204,7 @@ class XmlFormat extends Format
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
libxml_use_internal_errors(true);
|
libxml_use_internal_errors(true);
|
||||||
|
libxml_disable_entity_loader(true);
|
||||||
$xml = simplexml_load_string($data,
|
$xml = simplexml_load_string($data,
|
||||||
"SimpleXMLElement", LIBXML_NOBLANKS | LIBXML_NOCDATA | LIBXML_COMPACT);
|
"SimpleXMLElement", LIBXML_NOBLANKS | LIBXML_NOCDATA | LIBXML_COMPACT);
|
||||||
if (false === $xml) {
|
if (false === $xml) {
|
||||||
@ -241,8 +229,10 @@ class XmlFormat extends Format
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$data = $this->read($xml);
|
$data = $this->read($xml);
|
||||||
if (count($data) == 1 && isset($data[static::$textNodeName]))
|
if (count($data) == 1 && isset($data[static::$textNodeName])) {
|
||||||
$data = $data[static::$textNodeName];
|
$data = $data[static::$textNodeName];
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
throw new RestException(400,
|
throw new RestException(400,
|
||||||
@ -268,10 +258,13 @@ class XmlFormat extends Format
|
|||||||
}
|
}
|
||||||
$children = $xml->children();
|
$children = $xml->children();
|
||||||
foreach ($children as $key => $value) {
|
foreach ($children as $key => $value) {
|
||||||
if (isset($r[$key])) {
|
if ($key == static::$defaultTagName) {
|
||||||
|
$r[] = $this->read($value);
|
||||||
|
} elseif (isset($r[$key])) {
|
||||||
if (is_array($r[$key])) {
|
if (is_array($r[$key])) {
|
||||||
if ($r[$key] != array_values($r[$key]))
|
if ($r[$key] != array_values($r[$key])) {
|
||||||
$r[$key] = array($r[$key]);
|
$r[$key] = array($r[$key]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$r[$key] = array($r[$key]);
|
$r[$key] = array($r[$key]);
|
||||||
}
|
}
|
||||||
@ -282,8 +275,9 @@ class XmlFormat extends Format
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (static::$parseNamespaces) {
|
if (static::$parseNamespaces) {
|
||||||
if (is_null($namespaces))
|
if (is_null($namespaces)) {
|
||||||
$namespaces = $xml->getDocNamespaces(true);
|
$namespaces = $xml->getDocNamespaces(true);
|
||||||
|
}
|
||||||
foreach ($namespaces as $prefix => $ns) {
|
foreach ($namespaces as $prefix => $ns) {
|
||||||
static::$namespaces[$prefix] = $ns;
|
static::$namespaces[$prefix] = $ns;
|
||||||
if (static::$parseAttributes) {
|
if (static::$parseAttributes) {
|
||||||
@ -303,12 +297,14 @@ class XmlFormat extends Format
|
|||||||
}
|
}
|
||||||
$children = $xml->children($ns);
|
$children = $xml->children($ns);
|
||||||
foreach ($children as $key => $value) {
|
foreach ($children as $key => $value) {
|
||||||
if (static::$importSettingsFromXml)
|
if (static::$importSettingsFromXml) {
|
||||||
static::$namespacedProperties[$key] = $prefix;
|
static::$namespacedProperties[$key] = $prefix;
|
||||||
|
}
|
||||||
if (isset($r[$key])) {
|
if (isset($r[$key])) {
|
||||||
if (is_array($r[$key])) {
|
if (is_array($r[$key])) {
|
||||||
if ($r[$key] != array_values($r[$key]))
|
if ($r[$key] != array_values($r[$key])) {
|
||||||
$r[$key] = array($r[$key]);
|
$r[$key] = array($r[$key]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$r[$key] = array($r[$key]);
|
$r[$key] = array($r[$key]);
|
||||||
}
|
}
|
||||||
@ -321,7 +317,9 @@ class XmlFormat extends Format
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($text) && $text !== '0') {
|
if (empty($text) && $text !== '0') {
|
||||||
if (empty($r)) return null;
|
if (empty($r)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
empty($r)
|
empty($r)
|
||||||
? $r = static::setType($text)
|
? $r = static::setType($text)
|
||||||
@ -331,18 +329,25 @@ class XmlFormat extends Format
|
|||||||
: $r[] = static::setType($text)
|
: $r[] = static::setType($text)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setType($value)
|
public static function setType($value)
|
||||||
{
|
{
|
||||||
if (empty($value) && $value !== '0')
|
if (empty($value) && $value !== '0') {
|
||||||
return null;
|
return null;
|
||||||
if ($value == 'true')
|
}
|
||||||
|
if ($value == 'true') {
|
||||||
return true;
|
return true;
|
||||||
if ($value == 'false')
|
}
|
||||||
|
if ($value == 'false') {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return 0 + $value;
|
||||||
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,22 +14,23 @@ use Luracast\Restler\Data\Object;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class YamlFormat extends Format
|
class YamlFormat extends DependentFormat
|
||||||
{
|
{
|
||||||
const MIME = 'text/plain';
|
const MIME = 'text/plain';
|
||||||
const EXTENSION = 'yaml';
|
const EXTENSION = 'yaml';
|
||||||
|
|
||||||
|
const PACKAGE_NAME = 'symfony/yaml:*';
|
||||||
|
const EXTERNAL_CLASS = 'Symfony\Component\Yaml\Yaml';
|
||||||
|
|
||||||
public function encode($data, $humanReadable = false)
|
public function encode($data, $humanReadable = false)
|
||||||
{
|
{
|
||||||
// require_once 'sfyaml.php';
|
return @Yaml::dump(Object::toArray($data), $humanReadable ? 10 : 4);
|
||||||
return @Yaml::dump(Object::toArray($data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decode($data)
|
public function decode($data)
|
||||||
{
|
{
|
||||||
// require_once 'sfyaml.php';
|
|
||||||
return Yaml::parse($data);
|
return Yaml::parse($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Format;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iDecodeStream
|
interface iDecodeStream
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler\Format;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iFormat
|
interface iFormat
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class HumanReadableCache implements iCache
|
class HumanReadableCache implements iCache
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special RestException for forcing the exception even when
|
||||||
|
* in hybrid method
|
||||||
|
*
|
||||||
|
* @category Framework
|
||||||
|
* @package Restler
|
||||||
|
* @subpackage exception
|
||||||
|
* @author R.Arul Kumaran <arul@luracast.com>
|
||||||
|
* @copyright 2010 Luracast
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://luracast.com/products/restler/
|
||||||
|
* @version 3.0.0rc6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidAuthCredentials extends RestException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
<?php
|
||||||
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MemcacheCache provides a memcache based cache for Restler
|
||||||
|
*
|
||||||
|
* @category Framework
|
||||||
|
* @package Restler
|
||||||
|
* @author Dave Drager <ddrager@gmail.com>
|
||||||
|
* @copyright 2014 Luracast
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://luracast.com/products/restler/
|
||||||
|
* @version 3.0.0rc5
|
||||||
|
*/
|
||||||
|
class MemcacheCache implements iCache
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The namespace that all of the cached entries will be stored under. This allows multiple APIs to run concurrently.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
static public $namespace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string the memcache server hostname / IP address. For the memcache
|
||||||
|
* cache method.
|
||||||
|
*/
|
||||||
|
static public $memcacheServer = '127.0.0.1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int the memcache server port. For the memcache cache method.
|
||||||
|
*/
|
||||||
|
static public $memcachePort = 11211;
|
||||||
|
|
||||||
|
|
||||||
|
private $memcache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $namespace
|
||||||
|
*/
|
||||||
|
function __construct($namespace = 'restler')
|
||||||
|
{
|
||||||
|
self::$namespace = $namespace;
|
||||||
|
if (function_exists('memcache_connect')) {
|
||||||
|
$this->memcache = new \Memcache;
|
||||||
|
$this->memcache->connect(self::$memcacheServer, self::$memcachePort);
|
||||||
|
} else {
|
||||||
|
$this->memcacheNotAvailable('Memcache is not available for use as Restler Cache. Please make sure the the memcache php extension is installed.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* store data in the cache
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param mixed $data
|
||||||
|
*
|
||||||
|
* @return boolean true if successful
|
||||||
|
*/
|
||||||
|
public function set($name, $data)
|
||||||
|
{
|
||||||
|
function_exists('memcache_set') || $this->memcacheNotAvailable();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->memcache->set(self::$namespace . "-" . $name, $data);
|
||||||
|
} catch
|
||||||
|
(\Exception $exception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function memcacheNotAvailable($message = 'Memcache is not available.')
|
||||||
|
{
|
||||||
|
throw new \Exception($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve data from the cache
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param bool $ignoreErrors
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function get($name, $ignoreErrors = false)
|
||||||
|
{
|
||||||
|
function_exists('memcache_get') || $this->memcacheNotAvailable();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->memcache->get(self::$namespace . "-" . $name);
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
if (!$ignoreErrors) {
|
||||||
|
throw $exception;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete data from the cache
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param bool $ignoreErrors
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
* @return boolean true if successful
|
||||||
|
*/
|
||||||
|
public function clear($name, $ignoreErrors = false)
|
||||||
|
{
|
||||||
|
function_exists('memcache_delete') || $this->memcacheNotAvailable();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->memcache->delete(self::$namespace . "-" . $name);
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
if (!$ignoreErrors) {
|
||||||
|
throw $exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the given name is cached
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return boolean true if cached
|
||||||
|
*/
|
||||||
|
public function isCached($name)
|
||||||
|
{
|
||||||
|
function_exists('memcache_get') || $this->memcacheNotAvailable();
|
||||||
|
$data = $this->memcache->get(self::$namespace . "-" . $name);
|
||||||
|
return !empty($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static Class to pass through content outside of web root
|
||||||
|
*
|
||||||
|
* @category Framework
|
||||||
|
* @package Restler
|
||||||
|
* @author R.Arul Kumaran <arul@luracast.com>
|
||||||
|
* @copyright 2010 Luracast
|
||||||
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
|
* @link http://luracast.com/products/restler/
|
||||||
|
* @version 3.0.0rc6
|
||||||
|
*/
|
||||||
|
class PassThrough
|
||||||
|
{
|
||||||
|
public static $mimeTypes = array(
|
||||||
|
'js' => 'text/javascript',
|
||||||
|
'css' => 'text/css',
|
||||||
|
'png' => 'image/png',
|
||||||
|
'jpg' => 'image/jpeg',
|
||||||
|
'gif' => 'image/gif',
|
||||||
|
'html' => 'text/html',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve a file outside web root
|
||||||
|
*
|
||||||
|
* Respond with a file stored outside web accessible path
|
||||||
|
*
|
||||||
|
* @param string $filename full path for the file to be served
|
||||||
|
* @param bool $forceDownload should the we download instead of viewing
|
||||||
|
* @param int $expires cache expiry in number of seconds
|
||||||
|
* @param bool $isPublic cache control, is it public or private
|
||||||
|
*
|
||||||
|
* @throws RestException
|
||||||
|
* @internal param string $pragma
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static function file($filename, $forceDownload = false, $expires = 0, $isPublic = true)
|
||||||
|
{
|
||||||
|
if (!is_file($filename))
|
||||||
|
throw new RestException(404);
|
||||||
|
if (!is_readable($filename))
|
||||||
|
throw new RestException(403);
|
||||||
|
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||||
|
if (!$mime = Util::nestedValue(static::$mimeTypes, $extension)) {
|
||||||
|
if (!function_exists('finfo_open')) {
|
||||||
|
throw new RestException(
|
||||||
|
500,
|
||||||
|
'Unable to find media type of ' .
|
||||||
|
basename($filename) .
|
||||||
|
' either enable fileinfo php extension or update ' .
|
||||||
|
'PassThrough::$mimeTypes to include mime type for ' . $extension .
|
||||||
|
' extension'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||||
|
$mime = finfo_file($finfo, $filename);
|
||||||
|
}
|
||||||
|
if (!is_array(Defaults::$headerCacheControl))
|
||||||
|
Defaults::$headerCacheControl = array(Defaults::$headerCacheControl);
|
||||||
|
$cacheControl = Defaults::$headerCacheControl[0];
|
||||||
|
if ($expires > 0) {
|
||||||
|
$cacheControl = $isPublic ? 'public' : 'private';
|
||||||
|
$cacheControl .= end(Defaults::$headerCacheControl);
|
||||||
|
$cacheControl = str_replace('{expires}', $expires, $cacheControl);
|
||||||
|
$expires = gmdate('D, d M Y H:i:s \G\M\T', time() + $expires);
|
||||||
|
}
|
||||||
|
header('Cache-Control: ' . $cacheControl);
|
||||||
|
header('Expires: ' . $expires);
|
||||||
|
$lastModified = filemtime($filename);
|
||||||
|
if (
|
||||||
|
isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
|
||||||
|
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified
|
||||||
|
) {
|
||||||
|
header("{$_SERVER['SERVER_PROTOCOL']} 304 Not Modified");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
header('Last-Modified: ' . date('r', $lastModified));
|
||||||
|
header('X-Powered-By: Luracast Restler v' . Restler::VERSION);
|
||||||
|
header('Content-type: ' . $mime);
|
||||||
|
header("Content-Length: " . filesize($filename));
|
||||||
|
if ($forceDownload) {
|
||||||
|
header("Content-Transfer-Encoding: binary");
|
||||||
|
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||||
|
}
|
||||||
|
readfile($filename);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ use Luracast\Restler\Format\JsonFormat;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Redirect
|
class Redirect
|
||||||
{
|
{
|
||||||
@ -32,11 +32,13 @@ class Redirect
|
|||||||
/** @var $r Restler */
|
/** @var $r Restler */
|
||||||
$r = Scope::get('Restler');
|
$r = Scope::get('Restler');
|
||||||
$base = $r->getBaseUrl() . '/';
|
$base = $r->getBaseUrl() . '/';
|
||||||
if (0 !== strpos($url, 'http'))
|
if (0 !== strpos($url, 'http')) {
|
||||||
$url = $base . $url;
|
$url = $base . $url;
|
||||||
|
}
|
||||||
if (!empty($flashData) || $base . $r->url !== $url || Util::getRequestMethod() != 'GET') {
|
if (!empty($flashData) || $base . $r->url !== $url || Util::getRequestMethod() != 'GET') {
|
||||||
if ($r->responseFormat instanceof JsonFormat)
|
if ($r->responseFormat instanceof JsonFormat) {
|
||||||
return array('redirect' => $url);
|
return array('redirect' => $url);
|
||||||
|
}
|
||||||
if (!empty($params)) {
|
if (!empty($params)) {
|
||||||
$url .= '?' . http_build_query($params);
|
$url .= '?' . http_build_query($params);
|
||||||
}
|
}
|
||||||
@ -48,6 +50,19 @@ class Redirect
|
|||||||
header("Location: $url");
|
header("Location: $url");
|
||||||
die('');
|
die('');
|
||||||
}
|
}
|
||||||
|
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect back to the previous page
|
||||||
|
*
|
||||||
|
* Makes use of http referrer for redirection
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function back()
|
||||||
|
{
|
||||||
|
return static::to($_SERVER['HTTP_REFERER']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Luracast\Restler;
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
use Luracast\Restler\Data\String;
|
use Luracast\Restler\Data\Text;
|
||||||
use Luracast\Restler\Scope;
|
use Luracast\Restler\Scope;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ use stdClass;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
||||||
{
|
{
|
||||||
@ -226,14 +226,14 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$fullPath = $route['url'];
|
$fullPath = $route['url'];
|
||||||
if ($fullPath !== $target && !String::beginsWith($fullPath, $target)) {
|
if ($fullPath !== $target && !Text::beginsWith($fullPath, $target)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$fLen = strlen($fullPath);
|
$fLen = strlen($fullPath);
|
||||||
if ($tSlash) {
|
if ($tSlash) {
|
||||||
if ($fLen != $tLen && !String::beginsWith($fullPath, $target . '/'))
|
if ($fLen != $tLen && !Text::beginsWith($fullPath, $target . '/'))
|
||||||
continue;
|
continue;
|
||||||
} elseif ($fLen > $tLen + 1 && $fullPath{$tLen + 1} != '{' && !String::beginsWith($fullPath, '{')) {
|
} elseif ($fLen > $tLen + 1 && $fullPath{$tLen + 1} != '{' && !Text::beginsWith($fullPath, '{')) {
|
||||||
//when mapped to root exclude paths that have static parts
|
//when mapped to root exclude paths that have static parts
|
||||||
//they are listed else where under that static part name
|
//they are listed else where under that static part name
|
||||||
continue;
|
continue;
|
||||||
@ -246,7 +246,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
if (empty($exclude)) {
|
if (empty($exclude)) {
|
||||||
if ($fullPath == $exclude)
|
if ($fullPath == $exclude)
|
||||||
continue 2;
|
continue 2;
|
||||||
} elseif (String::beginsWith($fullPath, $exclude)) {
|
} elseif (Text::beginsWith($fullPath, $exclude)) {
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,7 +317,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
if (isset($m['throws'])) {
|
if (isset($m['throws'])) {
|
||||||
foreach ($m['throws'] as $exception) {
|
foreach ($m['throws'] as $exception) {
|
||||||
$operation->errorResponses[] = array(
|
$operation->errorResponses[] = array(
|
||||||
'reason' => $exception['reason'],
|
'reason' => $exception['message'],
|
||||||
'code' => $exception['code']);
|
'code' => $exception['code']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,7 +370,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
|
|
||||||
if (static::$groupOperations) {
|
if (static::$groupOperations) {
|
||||||
foreach ($r->apis as $a) {
|
foreach ($r->apis as $a) {
|
||||||
if ($a->path == "/$fullPath") {
|
if ($a->path == "$prefix/$fullPath") {
|
||||||
$api = $a;
|
$api = $a;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -774,14 +774,14 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
$this->_model($itemType);
|
$this->_model($itemType);
|
||||||
$itemType = $this->_noNamespace($itemType);
|
$itemType = $this->_noNamespace($itemType);
|
||||||
}
|
}
|
||||||
$properties[$key]['item'] = array(
|
$properties[$key]['items'] = array(
|
||||||
'type' => $itemType,
|
'type' => $itemType,
|
||||||
/*'description' => '' */ //TODO: add description
|
/*'description' => '' */ //TODO: add description
|
||||||
);
|
);
|
||||||
} else if (preg_match('/^Array\[(.+)\]$/', $type, $matches)) {
|
} else if (preg_match('/^Array\[(.+)\]$/', $type, $matches)) {
|
||||||
$itemType = $matches[1];
|
$itemType = $matches[1];
|
||||||
$properties[$key]['type'] = 'Array';
|
$properties[$key]['type'] = 'Array';
|
||||||
$properties[$key]['item']['type'] = $itemType;
|
$properties[$key]['items']['type'] = $this->_noNamespace($itemType);
|
||||||
|
|
||||||
if (class_exists($itemType)) {
|
if (class_exists($itemType)) {
|
||||||
$this->_model($itemType);
|
$this->_model($itemType);
|
||||||
@ -891,7 +891,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
}
|
}
|
||||||
$this->_mapResources($allRoutes, $map, $version);
|
$this->_mapResources($allRoutes, $map, $version);
|
||||||
foreach ($map as $path => $description) {
|
foreach ($map as $path => $description) {
|
||||||
if (!String::contains($path, '{')) {
|
if (!Text::contains($path, '{')) {
|
||||||
//add id
|
//add id
|
||||||
$r->apis[] = array(
|
$r->apis[] = array(
|
||||||
'path' => $path . $this->formatString,
|
'path' => $path . $this->formatString,
|
||||||
@ -934,7 +934,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
foreach ($allRoutes as $fullPath => $routes) {
|
foreach ($allRoutes as $fullPath => $routes) {
|
||||||
$path = explode('/', $fullPath);
|
$path = explode('/', $fullPath);
|
||||||
$resource = isset($path[0]) ? $path[0] : '';
|
$resource = isset($path[0]) ? $path[0] : '';
|
||||||
if ($resource == 'resources' || String::endsWith($resource, 'index'))
|
if ($resource == 'resources' || Text::endsWith($resource, 'index'))
|
||||||
continue;
|
continue;
|
||||||
foreach ($routes as $httpMethod => $route) {
|
foreach ($routes as $httpMethod => $route) {
|
||||||
if (in_array($httpMethod, static::$excludedHttpMethods)) {
|
if (in_array($httpMethod, static::$excludedHttpMethods)) {
|
||||||
@ -948,7 +948,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi
|
|||||||
if (empty($exclude)) {
|
if (empty($exclude)) {
|
||||||
if ($fullPath == $exclude)
|
if ($fullPath == $exclude)
|
||||||
continue 2;
|
continue 2;
|
||||||
} elseif (String::beginsWith($fullPath, $exclude)) {
|
} elseif (Text::beginsWith($fullPath, $exclude)) {
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ use Exception;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class RestException extends Exception
|
class RestException extends Exception
|
||||||
|
|||||||
@ -21,11 +21,37 @@ use Luracast\Restler\Format\UrlEncodedFormat;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
|
*
|
||||||
|
* @method static void onGet() onGet(Callable $function) fired before reading the request details
|
||||||
|
* @method static void onRoute() onRoute(Callable $function) fired before finding the api method
|
||||||
|
* @method static void onNegotiate() onNegotiate(Callable $function) fired before content negotiation
|
||||||
|
* @method static void onPreAuthFilter() onPreAuthFilter(Callable $function) fired before pre auth filtering
|
||||||
|
* @method static void onAuthenticate() onAuthenticate(Callable $function) fired before auth
|
||||||
|
* @method static void onPostAuthFilter() onPostAuthFilter(Callable $function) fired before post auth filtering
|
||||||
|
* @method static void onValidate() onValidate(Callable $function) fired before validation
|
||||||
|
* @method static void onCall() onCall(Callable $function) fired before api method call
|
||||||
|
* @method static void onCompose() onCompose(Callable $function) fired before composing response
|
||||||
|
* @method static void onRespond() onRespond(Callable $function) fired before sending response
|
||||||
|
* @method static void onComplete() onComplete(Callable $function) fired after sending response
|
||||||
|
* @method static void onMessage() onMessage(Callable $function) fired before composing error response
|
||||||
|
*
|
||||||
|
* @method void onGet() onGet(Callable $function) fired before reading the request details
|
||||||
|
* @method void onRoute() onRoute(Callable $function) fired before finding the api method
|
||||||
|
* @method void onNegotiate() onNegotiate(Callable $function) fired before content negotiation
|
||||||
|
* @method void onPreAuthFilter() onPreAuthFilter(Callable $function) fired before pre auth filtering
|
||||||
|
* @method void onAuthenticate() onAuthenticate(Callable $function) fired before auth
|
||||||
|
* @method void onPostAuthFilter() onPostAuthFilter(Callable $function) fired before post auth filtering
|
||||||
|
* @method void onValidate() onValidate(Callable $function) fired before validation
|
||||||
|
* @method void onCall() onCall(Callable $function) fired before api method call
|
||||||
|
* @method void onCompose() onCompose(Callable $function) fired before composing response
|
||||||
|
* @method void onRespond() onRespond(Callable $function) fired before sending response
|
||||||
|
* @method void onComplete() onComplete(Callable $function) fired after sending response
|
||||||
|
* @method void onMessage() onMessage(Callable $function) fired before composing error response
|
||||||
*/
|
*/
|
||||||
class Restler extends EventDispatcher
|
class Restler extends EventDispatcher
|
||||||
{
|
{
|
||||||
const VERSION = '3.0.0rc5';
|
const VERSION = '3.0.0rc6';
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
//
|
//
|
||||||
@ -78,9 +104,9 @@ class Restler extends EventDispatcher
|
|||||||
/**
|
/**
|
||||||
* Http status code
|
* Http status code
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int|null when specified it will override @status comment
|
||||||
*/
|
*/
|
||||||
public $responseCode=200;
|
public $responseCode=null;
|
||||||
/**
|
/**
|
||||||
* @var string base url of the api service
|
* @var string base url of the api service
|
||||||
*/
|
*/
|
||||||
@ -278,11 +304,20 @@ class Restler extends EventDispatcher
|
|||||||
$this->call();
|
$this->call();
|
||||||
$this->compose();
|
$this->compose();
|
||||||
$this->postCall();
|
$this->postCall();
|
||||||
|
if (Defaults::$returnResponse) {
|
||||||
|
return $this->respond();
|
||||||
|
}
|
||||||
$this->respond();
|
$this->respond();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
try{
|
try{
|
||||||
|
if (Defaults::$returnResponse) {
|
||||||
|
return $this->message($e);
|
||||||
|
}
|
||||||
$this->message($e);
|
$this->message($e);
|
||||||
} catch (Exception $e2) {
|
} catch (Exception $e2) {
|
||||||
|
if (Defaults::$returnResponse) {
|
||||||
|
return $this->message($e2);
|
||||||
|
}
|
||||||
$this->message($e2);
|
$this->message($e2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,6 +461,31 @@ class Restler extends EventDispatcher
|
|||||||
$this->formatOverridesMap['extensions'] = array_keys($extensions);
|
$this->formatOverridesMap['extensions'] = array_keys($extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set one or more string to be considered as the base url
|
||||||
|
*
|
||||||
|
* When more than one base url is provided, restler will make
|
||||||
|
* use of $_SERVER['HTTP_HOST'] to find the right one
|
||||||
|
*
|
||||||
|
* @param string ,... $url
|
||||||
|
*/
|
||||||
|
public function setBaseUrls($url /*[, $url2...$urlN]*/)
|
||||||
|
{
|
||||||
|
if (func_num_args() > 1) {
|
||||||
|
$urls = func_get_args();
|
||||||
|
usort($urls, function ($a, $b) {
|
||||||
|
return strlen($a) - strlen($b);
|
||||||
|
});
|
||||||
|
foreach ($urls as $u) {
|
||||||
|
if (0 === strpos($_SERVER['HTTP_HOST'], parse_url($u, PHP_URL_HOST))) {
|
||||||
|
$this->baseUrl = $u;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->baseUrl = $url;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the request url and get the api path
|
* Parses the request url and get the api path
|
||||||
*
|
*
|
||||||
@ -436,35 +496,43 @@ class Restler extends EventDispatcher
|
|||||||
// fix SCRIPT_NAME for PHP 5.4 built-in web server
|
// fix SCRIPT_NAME for PHP 5.4 built-in web server
|
||||||
if (false === strpos($_SERVER['SCRIPT_NAME'], '.php'))
|
if (false === strpos($_SERVER['SCRIPT_NAME'], '.php'))
|
||||||
$_SERVER['SCRIPT_NAME']
|
$_SERVER['SCRIPT_NAME']
|
||||||
= '/' . Util::removeCommonPath($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT']);
|
= '/' . substr($_SERVER['SCRIPT_FILENAME'], strlen($_SERVER['DOCUMENT_ROOT']) + 1);
|
||||||
|
|
||||||
$fullPath = urldecode($_SERVER['REQUEST_URI']);
|
list($base, $path) = Util::splitCommonPath(
|
||||||
$path = Util::removeCommonPath(
|
strtok(urldecode($_SERVER['REQUEST_URI']), '?'), //remove query string
|
||||||
$fullPath,
|
|
||||||
$_SERVER['SCRIPT_NAME']
|
$_SERVER['SCRIPT_NAME']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!$this->baseUrl) {
|
||||||
|
// Fix port number retrieval if port is specified in HOST header.
|
||||||
|
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
|
||||||
|
$portPos = strpos($host,":");
|
||||||
|
if ($portPos){
|
||||||
|
$port = substr($host,$portPos+1);
|
||||||
|
} else {
|
||||||
$port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '80';
|
$port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '80';
|
||||||
|
$port = isset($_SERVER['HTTP_X_FORWARDED_PORT']) ? $_SERVER['HTTP_X_FORWARDED_PORT'] : $port; // Amazon ELB
|
||||||
|
}
|
||||||
$https = $port == '443' ||
|
$https = $port == '443' ||
|
||||||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || // Amazon ELB
|
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || // Amazon ELB
|
||||||
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on');
|
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on');
|
||||||
|
|
||||||
$baseUrl = ($https ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'];
|
$baseUrl = ($https ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'];
|
||||||
|
|
||||||
if (!$https && $port != '80' || $https && $port != '443')
|
if (!$https && $port != '80' || $https && $port != '443')
|
||||||
$baseUrl .= ':' . $port;
|
$baseUrl .= ':' . $port;
|
||||||
|
$this->baseUrl = $baseUrl . $base;
|
||||||
|
} elseif (!empty($base) && false === strpos($this->baseUrl, $base)) {
|
||||||
|
$this->baseUrl .= $base;
|
||||||
|
}
|
||||||
|
|
||||||
$this->baseUrl = rtrim($baseUrl
|
|
||||||
. substr($fullPath, 0, strlen($fullPath) - strlen($path)), '/');
|
|
||||||
|
|
||||||
$path = rtrim(strtok($path, '?'), '/'); //remove query string and trailing slash if found any
|
|
||||||
$path = str_replace(
|
$path = str_replace(
|
||||||
array_merge(
|
array_merge(
|
||||||
$this->formatMap['extensions'],
|
$this->formatMap['extensions'],
|
||||||
$this->formatOverridesMap['extensions']
|
$this->formatOverridesMap['extensions']
|
||||||
),
|
),
|
||||||
'',
|
'',
|
||||||
$path
|
rtrim($path, '/') //remove trailing slash if found
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Defaults::$useUrlBasedVersioning && strlen($path) && $path{0} == 'v') {
|
if (Defaults::$useUrlBasedVersioning && strlen($path) && $path{0} == 'v') {
|
||||||
$version = intval(substr($path, 1));
|
$version = intval(substr($path, 1));
|
||||||
if ($version && $version <= $this->apiVersion) {
|
if ($version && $version <= $this->apiVersion) {
|
||||||
@ -865,23 +933,21 @@ class Restler extends EventDispatcher
|
|||||||
|
|
||||||
protected function authenticate()
|
protected function authenticate()
|
||||||
{
|
{
|
||||||
$o = & $this->apiMethodInfo;
|
$o = &$this->apiMethodInfo;
|
||||||
$accessLevel = max(Defaults::$apiAccessLevel,
|
$accessLevel = max(Defaults::$apiAccessLevel, $o->accessLevel);
|
||||||
$o->accessLevel);
|
|
||||||
try {
|
|
||||||
if ($accessLevel || count($this->postAuthFilterClasses)) {
|
if ($accessLevel || count($this->postAuthFilterClasses)) {
|
||||||
$this->dispatch('authenticate');
|
$this->dispatch('authenticate');
|
||||||
if (!count($this->authClasses)) {
|
if (!count($this->authClasses) && $accessLevel > 1) {
|
||||||
throw new RestException(
|
throw new RestException(
|
||||||
403,
|
403,
|
||||||
'at least one Authentication Class is required'
|
'at least one Authentication Class is required'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$unauthorized = false;
|
||||||
foreach ($this->authClasses as $authClass) {
|
foreach ($this->authClasses as $authClass) {
|
||||||
|
try {
|
||||||
$authObj = Scope::get($authClass);
|
$authObj = Scope::get($authClass);
|
||||||
if (!method_exists($authObj,
|
if (!method_exists($authObj, Defaults::$authenticationMethod)) {
|
||||||
Defaults::$authenticationMethod)
|
|
||||||
) {
|
|
||||||
throw new RestException (
|
throw new RestException (
|
||||||
500, 'Authentication Class ' .
|
500, 'Authentication Class ' .
|
||||||
'should implement iAuthenticate');
|
'should implement iAuthenticate');
|
||||||
@ -890,17 +956,27 @@ class Restler extends EventDispatcher
|
|||||||
) {
|
) {
|
||||||
throw new RestException(401);
|
throw new RestException(401);
|
||||||
}
|
}
|
||||||
}
|
$unauthorized = false;
|
||||||
$this->authenticated = true;
|
break;
|
||||||
}
|
} catch (InvalidAuthCredentials $e) {
|
||||||
$this->authVerified = true;
|
$this->authenticated = false;
|
||||||
|
throw $e;
|
||||||
} catch (RestException $e) {
|
} catch (RestException $e) {
|
||||||
|
if (!$unauthorized) {
|
||||||
|
$unauthorized = $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$this->authVerified = true;
|
$this->authVerified = true;
|
||||||
|
if ($unauthorized) {
|
||||||
if ($accessLevel > 1) { //when it is not a hybrid api
|
if ($accessLevel > 1) { //when it is not a hybrid api
|
||||||
throw ($e);
|
throw $unauthorized;
|
||||||
} else {
|
} else {
|
||||||
$this->authenticated = false;
|
$this->authenticated = false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$this->authenticated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,6 +1012,8 @@ class Restler extends EventDispatcher
|
|||||||
}
|
}
|
||||||
//convert to instance of ValidationInfo
|
//convert to instance of ValidationInfo
|
||||||
$info = new ValidationInfo($param);
|
$info = new ValidationInfo($param);
|
||||||
|
//initialize validator
|
||||||
|
Scope::get(Defaults::$validatorClass);
|
||||||
$validator = Defaults::$validatorClass;
|
$validator = Defaults::$validatorClass;
|
||||||
//if(!is_subclass_of($validator, 'Luracast\\Restler\\Data\\iValidate')) {
|
//if(!is_subclass_of($validator, 'Luracast\\Restler\\Data\\iValidate')) {
|
||||||
//changed the above test to below for addressing this php bug
|
//changed the above test to below for addressing this php bug
|
||||||
@ -964,6 +1042,8 @@ class Restler extends EventDispatcher
|
|||||||
$o = & $this->apiMethodInfo;
|
$o = & $this->apiMethodInfo;
|
||||||
$accessLevel = max(Defaults::$apiAccessLevel,
|
$accessLevel = max(Defaults::$apiAccessLevel,
|
||||||
$o->accessLevel);
|
$o->accessLevel);
|
||||||
|
if (function_exists('newrelic_name_transaction'))
|
||||||
|
newrelic_name_transaction("{$o->className}/{$o->methodName}");
|
||||||
$object = Scope::get($o->className);
|
$object = Scope::get($o->className);
|
||||||
switch ($accessLevel) {
|
switch ($accessLevel) {
|
||||||
case 3 : //protected method
|
case 3 : //protected method
|
||||||
@ -1057,6 +1137,8 @@ class Restler extends EventDispatcher
|
|||||||
if (!Defaults::$suppressResponseCode) {
|
if (!Defaults::$suppressResponseCode) {
|
||||||
if ($e) {
|
if ($e) {
|
||||||
$code = $e->getCode();
|
$code = $e->getCode();
|
||||||
|
} elseif ($this->responseCode) {
|
||||||
|
$code = $this->responseCode;
|
||||||
} elseif (isset($this->apiMethodInfo->metadata['status'])) {
|
} elseif (isset($this->apiMethodInfo->metadata['status'])) {
|
||||||
$code = $this->apiMethodInfo->metadata['status'];
|
$code = $this->apiMethodInfo->metadata['status'];
|
||||||
}
|
}
|
||||||
@ -1084,10 +1166,14 @@ class Restler extends EventDispatcher
|
|||||||
: 'Unknown';
|
: 'Unknown';
|
||||||
@header('WWW-Authenticate: ' . $authString, false);
|
@header('WWW-Authenticate: ' . $authString, false);
|
||||||
}
|
}
|
||||||
echo $this->responseData;
|
|
||||||
$this->dispatch('complete');
|
$this->dispatch('complete');
|
||||||
|
if (Defaults::$returnResponse) {
|
||||||
|
return $this->responseData;
|
||||||
|
} else {
|
||||||
|
echo $this->responseData;
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function message(Exception $exception)
|
protected function message(Exception $exception)
|
||||||
{
|
{
|
||||||
@ -1128,6 +1214,9 @@ class Restler extends EventDispatcher
|
|||||||
$compose->message($exception),
|
$compose->message($exception),
|
||||||
!$this->productionMode
|
!$this->productionMode
|
||||||
);
|
);
|
||||||
|
if (Defaults::$returnResponse) {
|
||||||
|
return $this->respond();
|
||||||
|
}
|
||||||
$this->respond();
|
$this->respond();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
namespace Luracast\Restler;
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
use Luracast\Restler\Data\ApiMethodInfo;
|
use Luracast\Restler\Data\ApiMethodInfo;
|
||||||
use Luracast\Restler\Data\String;
|
use Luracast\Restler\Data\Text;
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
use ReflectionProperty;
|
use ReflectionProperty;
|
||||||
@ -17,13 +17,32 @@ use Exception;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Routes
|
class Routes
|
||||||
{
|
{
|
||||||
public static $prefixingParameterNames = array(
|
public static $prefixingParameterNames = array(
|
||||||
'id'
|
'id'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static $fieldTypesByName = array(
|
||||||
|
'email' => 'email',
|
||||||
|
'password' => 'password',
|
||||||
|
'phone' => 'tel',
|
||||||
|
'mobile' => 'tel',
|
||||||
|
'tel' => 'tel',
|
||||||
|
'search' => 'search',
|
||||||
|
'date' => 'date',
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'modified_at' => 'datetime',
|
||||||
|
'url' => 'url',
|
||||||
|
'link' => 'url',
|
||||||
|
'href' => 'url',
|
||||||
|
'website' => 'url',
|
||||||
|
'color' => 'color',
|
||||||
|
'colour' => 'color',
|
||||||
|
);
|
||||||
|
|
||||||
protected static $routes = array();
|
protected static $routes = array();
|
||||||
|
|
||||||
protected static $models = array();
|
protected static $models = array();
|
||||||
@ -56,6 +75,7 @@ class Routes
|
|||||||
* - Do not include it in URL
|
* - Do not include it in URL
|
||||||
*/
|
*/
|
||||||
$class = new ReflectionClass($className);
|
$class = new ReflectionClass($className);
|
||||||
|
$dataName = CommentParser::$embeddedDataName;
|
||||||
try {
|
try {
|
||||||
$classMetadata = CommentParser::parse($class->getDocComment());
|
$classMetadata = CommentParser::parse($class->getDocComment());
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
@ -92,7 +112,7 @@ class Routes
|
|||||||
= (isset($metadata['smart-auto-routing'])
|
= (isset($metadata['smart-auto-routing'])
|
||||||
&& $metadata['smart-auto-routing'] != 'true')
|
&& $metadata['smart-auto-routing'] != 'true')
|
||||||
|| !Defaults::$smartAutoRouting;
|
|| !Defaults::$smartAutoRouting;
|
||||||
$metadata['resourcePath'] = $resourcePath;
|
$metadata['resourcePath'] = trim($resourcePath, '/');
|
||||||
if (isset($classMetadata['description'])) {
|
if (isset($classMetadata['description'])) {
|
||||||
$metadata['classDescription'] = $classMetadata['description'];
|
$metadata['classDescription'] = $classMetadata['description'];
|
||||||
}
|
}
|
||||||
@ -123,44 +143,51 @@ class Routes
|
|||||||
}
|
}
|
||||||
$m = & $metadata ['param'] [$position];
|
$m = & $metadata ['param'] [$position];
|
||||||
$m ['name'] = $param->getName();
|
$m ['name'] = $param->getName();
|
||||||
|
if (!isset($m[$dataName])) {
|
||||||
|
$m[$dataName] = array();
|
||||||
|
}
|
||||||
|
$p = &$m[$dataName];
|
||||||
if (empty($m['label']))
|
if (empty($m['label']))
|
||||||
$m['label'] = static::label($m['name']);
|
$m['label'] = Text::title($m['name']);
|
||||||
if (is_null($type) && isset($m['type'])) {
|
if (is_null($type) && isset($m['type'])) {
|
||||||
$type = $m['type'];
|
$type = $m['type'];
|
||||||
}
|
}
|
||||||
if ($m['name'] == 'email' && empty($m[CommentParser::$embeddedDataName]['type']) && $type == 'string')
|
if (isset(static::$fieldTypesByName[$m['name']]) && empty($p['type']) && $type == 'string') {
|
||||||
$m[CommentParser::$embeddedDataName]['type'] = 'email';
|
$p['type'] = static::$fieldTypesByName[$m['name']];
|
||||||
|
}
|
||||||
$m ['default'] = $defaults [$position];
|
$m ['default'] = $defaults [$position];
|
||||||
$m ['required'] = !$param->isOptional();
|
$m ['required'] = !$param->isOptional();
|
||||||
$contentType = Util::nestedValue(
|
$contentType = Util::nestedValue($p,'type');
|
||||||
$m,
|
if ($type == 'array' && $contentType && $qualified = Scope::resolve($contentType, $scope)) {
|
||||||
CommentParser::$embeddedDataName,
|
list($p['type'], $children, $modelName) = static::getTypeAndModel(
|
||||||
'type'
|
new ReflectionClass($qualified), $scope,
|
||||||
);
|
$className . Text::title($methodUrl), $p
|
||||||
if ($contentType && $qualified = Scope::resolve($contentType, $scope)) {
|
|
||||||
list($m[CommentParser::$embeddedDataName]['type'], $children) = static::getTypeAndModel(
|
|
||||||
new ReflectionClass($qualified), $scope
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($type instanceof ReflectionClass) {
|
if ($type instanceof ReflectionClass) {
|
||||||
list($type, $children) = static::getTypeAndModel($type, $scope);
|
list($type, $children, $modelName) = static::getTypeAndModel($type, $scope,
|
||||||
|
$className . Text::title($methodUrl), $p);
|
||||||
} elseif ($type && is_string($type) && $qualified = Scope::resolve($type, $scope)) {
|
} elseif ($type && is_string($type) && $qualified = Scope::resolve($type, $scope)) {
|
||||||
list($type, $children)
|
list($type, $children, $modelName)
|
||||||
= static::getTypeAndModel(new ReflectionClass($qualified), $scope);
|
= static::getTypeAndModel(new ReflectionClass($qualified), $scope,
|
||||||
|
$className . Text::title($methodUrl), $p);
|
||||||
}
|
}
|
||||||
if (isset($type)) {
|
if (isset($type)) {
|
||||||
$m['type'] = $type;
|
$m['type'] = $type;
|
||||||
}
|
}
|
||||||
$m['children'] = $children;
|
|
||||||
|
|
||||||
|
$m['children'] = $children;
|
||||||
|
if (isset($modelName)) {
|
||||||
|
$m['model'] = $modelName;
|
||||||
|
}
|
||||||
if ($m['name'] == Defaults::$fullRequestDataName) {
|
if ($m['name'] == Defaults::$fullRequestDataName) {
|
||||||
$from = 'body';
|
$from = 'body';
|
||||||
if (!isset($m['type'])) {
|
if (!isset($m['type'])) {
|
||||||
$type = $m['type'] = 'array';
|
$type = $m['type'] = 'array';
|
||||||
}
|
}
|
||||||
|
|
||||||
} elseif (isset($m[CommentParser::$embeddedDataName]['from'])) {
|
} elseif (isset($p['from'])) {
|
||||||
$from = $m[CommentParser::$embeddedDataName]['from'];
|
$from = $p['from'];
|
||||||
} else {
|
} else {
|
||||||
if ((isset($type) && Util::isObjectOrArray($type))
|
if ((isset($type) && Util::isObjectOrArray($type))
|
||||||
) {
|
) {
|
||||||
@ -174,7 +201,7 @@ class Routes
|
|||||||
$from = 'body';
|
$from = 'body';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$m[CommentParser::$embeddedDataName]['from'] = $from;
|
$p['from'] = $from;
|
||||||
if (!isset($m['type'])) {
|
if (!isset($m['type'])) {
|
||||||
$type = $m['type'] = static::type($defaults[$position]);
|
$type = $m['type'] = static::type($defaults[$position]);
|
||||||
}
|
}
|
||||||
@ -229,21 +256,21 @@ class Routes
|
|||||||
strpos($url, '{' . $p['name'] . '}') ||
|
strpos($url, '{' . $p['name'] . '}') ||
|
||||||
strpos($url, ':' . $p['name']);
|
strpos($url, ':' . $p['name']);
|
||||||
if ($inPath) {
|
if ($inPath) {
|
||||||
$copy['metadata']['param'][$i][CommentParser::$embeddedDataName]['from'] = 'path';
|
$copy['metadata']['param'][$i][$dataName]['from'] = 'path';
|
||||||
} elseif ($httpMethod == 'GET' || $httpMethod == 'DELETE') {
|
} elseif ($httpMethod == 'GET' || $httpMethod == 'DELETE') {
|
||||||
$copy['metadata']['param'][$i][CommentParser::$embeddedDataName]['from'] = 'query';
|
$copy['metadata']['param'][$i][$dataName]['from'] = 'query';
|
||||||
} elseif ($p[CommentParser::$embeddedDataName]['from'] == 'path') {
|
} elseif (empty($p[$dataName]['from']) || $p[$dataName]['from'] == 'path') {
|
||||||
$copy['metadata']['param'][$i][CommentParser::$embeddedDataName]['from'] = 'body';
|
$copy['metadata']['param'][$i][$dataName]['from'] = 'body';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$url = preg_replace_callback('/{[^}]+}|:[^\/]+/',
|
$url = preg_replace_callback('/{[^}]+}|:[^\/]+/',
|
||||||
function ($matches) use ($call) {
|
function ($matches) use ($copy) {
|
||||||
$match = trim($matches[0], '{}:');
|
$match = trim($matches[0], '{}:');
|
||||||
$index = $call['arguments'][$match];
|
$index = $copy['arguments'][$match];
|
||||||
return '{' .
|
return '{' .
|
||||||
Routes::typeChar(isset(
|
Routes::typeChar(isset(
|
||||||
$call['metadata']['param'][$index]['type'])
|
$copy['metadata']['param'][$index]['type'])
|
||||||
? $call['metadata']['param'][$index]['type']
|
? $copy['metadata']['param'][$index]['type']
|
||||||
: null)
|
: null)
|
||||||
. $index . '}';
|
. $index . '}';
|
||||||
}, $url);
|
}, $url);
|
||||||
@ -269,11 +296,11 @@ class Routes
|
|||||||
$lastPathParam = array_keys($pathParams);
|
$lastPathParam = array_keys($pathParams);
|
||||||
$lastPathParam = end($lastPathParam);
|
$lastPathParam = end($lastPathParam);
|
||||||
for ($position = 0; $position < count($params); $position++) {
|
for ($position = 0; $position < count($params); $position++) {
|
||||||
$from = $metadata['param'][$position][CommentParser::$embeddedDataName]['from'];
|
$from = $metadata['param'][$position][$dataName]['from'];
|
||||||
if ($from == 'body' && ($httpMethod == 'GET' ||
|
if ($from == 'body' && ($httpMethod == 'GET' ||
|
||||||
$httpMethod == 'DELETE')
|
$httpMethod == 'DELETE')
|
||||||
) {
|
) {
|
||||||
$call['metadata']['param'][$position][CommentParser::$embeddedDataName]['from']
|
$call['metadata']['param'][$position][$dataName]['from']
|
||||||
= 'query';
|
= 'query';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,6 +458,62 @@ class Routes
|
|||||||
throw new RestException($status, $message);
|
throw new RestException($status, $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function findAll(array $excludedPaths = array(), array $excludedHttpMethods = array(), $version = 1)
|
||||||
|
{
|
||||||
|
$map = array();
|
||||||
|
$all = Util::nestedValue(self::$routes, "v$version");
|
||||||
|
$filter = array();
|
||||||
|
if (isset($all['*'])) {
|
||||||
|
$all = $all['*'] + $all;
|
||||||
|
unset($all['*']);
|
||||||
|
}
|
||||||
|
if(is_array($all)){
|
||||||
|
foreach ($all as $fullPath => $routes) {
|
||||||
|
foreach ($routes as $httpMethod => $route) {
|
||||||
|
if (in_array($httpMethod, $excludedHttpMethods)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach ($excludedPaths as $exclude) {
|
||||||
|
if (empty($exclude)) {
|
||||||
|
if ($fullPath == $exclude || $fullPath == 'index')
|
||||||
|
continue 2;
|
||||||
|
} elseif (Text::beginsWith($fullPath, $exclude)) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$hash = "$httpMethod " . $route['url'];
|
||||||
|
if (!isset($filter[$hash])) {
|
||||||
|
$route['httpMethod'] = $httpMethod;
|
||||||
|
$map[$route['metadata']['resourcePath']][]
|
||||||
|
= array('access' => static::verifyAccess($route), 'route' => $route, 'hash' => $hash);
|
||||||
|
$filter[$hash] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function verifyAccess($route)
|
||||||
|
{
|
||||||
|
if ($route['accessLevel'] < 2)
|
||||||
|
return true;
|
||||||
|
/** @var Restler $r */
|
||||||
|
$r = Scope::get('Restler');
|
||||||
|
$authenticated = $r->_authenticated;
|
||||||
|
if (!$authenticated && $route['accessLevel'] > 1)
|
||||||
|
return false;
|
||||||
|
if (
|
||||||
|
$authenticated &&
|
||||||
|
Defaults::$accessControlFunction &&
|
||||||
|
(!call_user_func(Defaults::$accessControlFunction, $route['metadata']))
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates the parameter values
|
* Populates the parameter values
|
||||||
*
|
*
|
||||||
@ -445,14 +528,14 @@ class Routes
|
|||||||
{
|
{
|
||||||
$call['parameters'] = $call['defaults'];
|
$call['parameters'] = $call['defaults'];
|
||||||
$p = & $call['parameters'];
|
$p = & $call['parameters'];
|
||||||
|
$dataName = CommentParser::$embeddedDataName;
|
||||||
foreach ($data as $key => $value) {
|
foreach ($data as $key => $value) {
|
||||||
if (isset($call['arguments'][$key])) {
|
if (isset($call['arguments'][$key])) {
|
||||||
$p[$call['arguments'][$key]] = $value;
|
$p[$call['arguments'][$key]] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Defaults::$smartParameterParsing && 'post' != (string)Util::$restler->requestFormat) {
|
if (Defaults::$smartParameterParsing) {
|
||||||
if (
|
if (
|
||||||
count($p) == 1 &&
|
|
||||||
($m = Util::nestedValue($call, 'metadata', 'param', 0)) &&
|
($m = Util::nestedValue($call, 'metadata', 'param', 0)) &&
|
||||||
!array_key_exists($m['name'], $data) &&
|
!array_key_exists($m['name'], $data) &&
|
||||||
array_key_exists(Defaults::$fullRequestDataName, $data) &&
|
array_key_exists(Defaults::$fullRequestDataName, $data) &&
|
||||||
@ -466,7 +549,7 @@ class Routes
|
|||||||
$lastBodyParamIndex = -1;
|
$lastBodyParamIndex = -1;
|
||||||
$lastM = null;
|
$lastM = null;
|
||||||
foreach ($call['metadata']['param'] as $k => $m) {
|
foreach ($call['metadata']['param'] as $k => $m) {
|
||||||
if ($m[CommentParser::$embeddedDataName]['from'] == 'body') {
|
if ($m[$dataName]['from'] == 'body') {
|
||||||
$bodyParamCount++;
|
$bodyParamCount++;
|
||||||
$lastBodyParamIndex = $k;
|
$lastBodyParamIndex = $k;
|
||||||
$lastM = $m;
|
$lastM = $m;
|
||||||
@ -526,6 +609,21 @@ class Routes
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function parseMagic(ReflectionClass $class, $forResponse = true)
|
||||||
|
{
|
||||||
|
if (!$c = CommentParser::parse($class->getDocComment())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$p = 'property';
|
||||||
|
$r = empty($c[$p]) ? array() : $c[$p];
|
||||||
|
$p .= '-' . ($forResponse ? 'read' : 'write');
|
||||||
|
if (!empty($c[$p])) {
|
||||||
|
$r = array_merge($r, $c[$p]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type and associated model
|
* Get the type and associated model
|
||||||
*
|
*
|
||||||
@ -538,14 +636,29 @@ class Routes
|
|||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
protected static function getTypeAndModel(ReflectionClass $class, array $scope)
|
protected static function getTypeAndModel(ReflectionClass $class, array $scope, $prefix='', array $rules=array())
|
||||||
{
|
{
|
||||||
$className = $class->getName();
|
$className = $class->getName();
|
||||||
if (isset(static::$models[$className])) {
|
$dataName = CommentParser::$embeddedDataName;
|
||||||
return static::$models[$className];
|
if (isset(static::$models[$prefix.$className])) {
|
||||||
|
return static::$models[$prefix.$className];
|
||||||
}
|
}
|
||||||
$children = array();
|
$children = array();
|
||||||
try {
|
try {
|
||||||
|
if ($magic_properties = static::parseMagic($class, empty($prefix))) {
|
||||||
|
foreach ($magic_properties as $prop) {
|
||||||
|
if (!isset($prop['name'])) {
|
||||||
|
throw new Exception('@property comment is not properly defined in ' . $className . ' class');
|
||||||
|
}
|
||||||
|
if (!isset($prop[$dataName]['label'])) {
|
||||||
|
$prop[$dataName]['label'] = Text::title($prop['name']);
|
||||||
|
}
|
||||||
|
if (isset(static::$fieldTypesByName[$prop['name']]) && $prop['type'] == 'string' && !isset($prop[$dataName]['type'])) {
|
||||||
|
$prop[$dataName]['type'] = static::$fieldTypesByName[$prop['name']];
|
||||||
|
}
|
||||||
|
$children[$prop['name']] = $prop;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
$props = $class->getProperties(ReflectionProperty::IS_PUBLIC);
|
$props = $class->getProperties(ReflectionProperty::IS_PUBLIC);
|
||||||
foreach ($props as $prop) {
|
foreach ($props as $prop) {
|
||||||
$name = $prop->getName();
|
$name = $prop->getName();
|
||||||
@ -568,17 +681,19 @@ class Routes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$child += array(
|
$child += array(
|
||||||
'type' => $child['name'] == 'email' ? 'email' : 'string',
|
'type' => isset(static::$fieldTypesByName[$child['name']])
|
||||||
'label' => static::label($child['name'])
|
? static::$fieldTypesByName[$child['name']]
|
||||||
|
: 'string',
|
||||||
|
'label' => Text::title($child['name'])
|
||||||
);
|
);
|
||||||
isset($child[CommentParser::$embeddedDataName])
|
isset($child[$dataName])
|
||||||
? $child[CommentParser::$embeddedDataName] += array('required' => true)
|
? $child[$dataName] += array('required' => true)
|
||||||
: $child[CommentParser::$embeddedDataName]['required'] = true;
|
: $child[$dataName]['required'] = true;
|
||||||
if ($qualified = Scope::resolve($child['type'], $scope)) {
|
if ($prop->class != $className && $qualified = Scope::resolve($child['type'], $scope)) {
|
||||||
list($child['type'], $child['children'])
|
list($child['type'], $child['children'])
|
||||||
= static::getTypeAndModel(new ReflectionClass($qualified), $scope);
|
= static::getTypeAndModel(new ReflectionClass($qualified), $scope);
|
||||||
} elseif (
|
} elseif (
|
||||||
($contentType = Util::nestedValue($child, CommentParser::$embeddedDataName, 'type')) &&
|
($contentType = Util::nestedValue($child, $dataName, 'type')) &&
|
||||||
($qualified = Scope::resolve($contentType, $scope))
|
($qualified = Scope::resolve($contentType, $scope))
|
||||||
) {
|
) {
|
||||||
list($child['contentType'], $child['children'])
|
list($child['contentType'], $child['children'])
|
||||||
@ -586,14 +701,40 @@ class Routes
|
|||||||
}
|
}
|
||||||
$children[$name] = $child;
|
$children[$name] = $child;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
if (String::endsWith($e->getFile(), 'CommentParser.php')) {
|
if (Text::endsWith($e->getFile(), 'CommentParser.php')) {
|
||||||
throw new RestException(500, "Error while parsing comments of `$className` class. " . $e->getMessage());
|
throw new RestException(500, "Error while parsing comments of `$className` class. " . $e->getMessage());
|
||||||
}
|
}
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
static::$models[$className] = array($className, $children);
|
if ($properties = Util::nestedValue($rules, 'properties')) {
|
||||||
return static::$models[$className];
|
if (is_string($properties)) {
|
||||||
|
$properties = array($properties);
|
||||||
|
}
|
||||||
|
$c = array();
|
||||||
|
foreach ($properties as $property) {
|
||||||
|
if (isset($children[$property])) {
|
||||||
|
$c[$property] = $children[$property];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$children = $c;
|
||||||
|
}
|
||||||
|
if ($required = Util::nestedValue($rules, 'required')) {
|
||||||
|
//override required on children
|
||||||
|
if (is_bool($required)) {
|
||||||
|
// true means all are required false means none are required
|
||||||
|
$required = $required ? array_keys($children) : array();
|
||||||
|
} elseif (is_string($required)) {
|
||||||
|
$required = array($required);
|
||||||
|
}
|
||||||
|
$required = array_fill_keys($required, true);
|
||||||
|
foreach ($children as $name => $child) {
|
||||||
|
$children[$name][$dataName]['required'] = isset($required[$name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static::$models[$prefix.$className] = array($className, $children, $prefix.$className);
|
||||||
|
return static::$models[$prefix.$className];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -625,20 +766,6 @@ class Routes
|
|||||||
return 'string';
|
return 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a label from name of the parameter or property
|
|
||||||
*
|
|
||||||
* Convert `camelCase` style names into proper `Title Case` names
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function label($name)
|
|
||||||
{
|
|
||||||
return ucfirst(preg_replace(array('/(?<=[^A-Z])([A-Z])/', '/(?<=[^0-9])([0-9])/'), ' $0', $name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function scope(ReflectionClass $class)
|
public static function scope(ReflectionClass $class)
|
||||||
{
|
{
|
||||||
$namespace = $class->getNamespaceName();
|
$namespace = $class->getNamespaceName();
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Scope
|
class Scope
|
||||||
{
|
{
|
||||||
@ -44,24 +44,37 @@ class Scope
|
|||||||
|
|
||||||
//API classes
|
//API classes
|
||||||
'Resources' => 'Luracast\Restler\Resources',
|
'Resources' => 'Luracast\Restler\Resources',
|
||||||
|
'Explorer' => 'Luracast\Restler\Explorer',
|
||||||
|
|
||||||
//Cache classes
|
//Cache classes
|
||||||
'HumanReadableCache' => 'Luracast\Restler\HumanReadableCache',
|
'HumanReadableCache' => 'Luracast\Restler\HumanReadableCache',
|
||||||
'ApcCache' => 'Luracast\Restler\ApcCache',
|
'ApcCache' => 'Luracast\Restler\ApcCache',
|
||||||
|
'MemcacheCache' => 'Luracast\Restler\MemcacheCache',
|
||||||
|
|
||||||
//Utility classes
|
//Utility classes
|
||||||
'Object' => 'Luracast\Restler\Data\Object',
|
'Object' => 'Luracast\Restler\Data\Object',
|
||||||
'String' => 'Luracast\Restler\Data\String',
|
'Text' => 'Luracast\Restler\Data\Text',
|
||||||
'Arr' => 'Luracast\Restler\Data\Arr',
|
'Arr' => 'Luracast\Restler\Data\Arr',
|
||||||
|
|
||||||
//Exception
|
//Exception
|
||||||
'RestException' => 'Luracast\Restler\RestException'
|
'RestException' => 'Luracast\Restler\RestException'
|
||||||
);
|
);
|
||||||
|
/**
|
||||||
|
* @var null|Callable adding a resolver function that accepts
|
||||||
|
* the class name as the parameter and returns an instance of the class
|
||||||
|
* as a singleton. Allows the use of your favourite DI container
|
||||||
|
*/
|
||||||
|
public static $resolver = null;
|
||||||
public static $properties = array();
|
public static $properties = array();
|
||||||
protected static $instances = array();
|
protected static $instances = array();
|
||||||
protected static $registry = array();
|
protected static $registry = array();
|
||||||
|
|
||||||
public static function register($name, Callable $function, $singleton = true)
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param callable $function
|
||||||
|
* @param bool $singleton
|
||||||
|
*/
|
||||||
|
public static function register($name, $function, $singleton = true)
|
||||||
{
|
{
|
||||||
static::$registry[$name] = (object)compact('function', 'singleton');
|
static::$registry[$name] = (object)compact('function', 'singleton');
|
||||||
}
|
}
|
||||||
@ -82,8 +95,19 @@ class Scope
|
|||||||
} elseif (!empty(static::$registry[$name])) {
|
} elseif (!empty(static::$registry[$name])) {
|
||||||
$function = static::$registry[$name]->function;
|
$function = static::$registry[$name]->function;
|
||||||
$r = $function();
|
$r = $function();
|
||||||
if (static::$registry[$name]->singleton)
|
if (static::$registry[$name]->singleton) {
|
||||||
static::$instances[$name] = (object)array('instance' => $r);
|
static::$instances[$name] = (object)array('instance' => $r);
|
||||||
|
}
|
||||||
|
} elseif (is_callable(static::$resolver) && false === stristr($name, 'Luracast\Restler')) {
|
||||||
|
$fullName = $name;
|
||||||
|
if (isset(static::$classAliases[$name])) {
|
||||||
|
$fullName = static::$classAliases[$name];
|
||||||
|
}
|
||||||
|
/** @var Callable $function */
|
||||||
|
$function = static::$resolver;
|
||||||
|
$r = $function($fullName);
|
||||||
|
static::$instances[$name] = (object)array('instance' => $r);
|
||||||
|
static::$instances[$name]->initPending = true;
|
||||||
} else {
|
} else {
|
||||||
$fullName = $name;
|
$fullName = $name;
|
||||||
if (isset(static::$classAliases[$name])) {
|
if (isset(static::$classAliases[$name])) {
|
||||||
@ -100,10 +124,10 @@ class Scope
|
|||||||
$properties = Util::nestedValue(
|
$properties = Util::nestedValue(
|
||||||
$m, 'class', $fullName,
|
$m, 'class', $fullName,
|
||||||
CommentParser::$embeddedDataName
|
CommentParser::$embeddedDataName
|
||||||
) ? : (Util::nestedValue(
|
) ?: (Util::nestedValue(
|
||||||
$m, 'class', $shortName,
|
$m, 'class', $shortName,
|
||||||
CommentParser::$embeddedDataName
|
CommentParser::$embeddedDataName
|
||||||
) ? : array());
|
) ?: array());
|
||||||
} else {
|
} else {
|
||||||
static::$instances[$name]->initPending = true;
|
static::$instances[$name]->initPending = true;
|
||||||
}
|
}
|
||||||
@ -126,17 +150,18 @@ class Scope
|
|||||||
$shortName = Util::getShortName($name);
|
$shortName = Util::getShortName($name);
|
||||||
} else {
|
} else {
|
||||||
$shortName = $name;
|
$shortName = $name;
|
||||||
if (isset(static::$classAliases[$name]))
|
if (isset(static::$classAliases[$name])) {
|
||||||
$fullName = static::$classAliases[$name];
|
$fullName = static::$classAliases[$name];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ($m) {
|
if ($m) {
|
||||||
$properties = Util::nestedValue(
|
$properties = Util::nestedValue(
|
||||||
$m, 'class', $fullName,
|
$m, 'class', $fullName,
|
||||||
CommentParser::$embeddedDataName
|
CommentParser::$embeddedDataName
|
||||||
) ? : (Util::nestedValue(
|
) ?: (Util::nestedValue(
|
||||||
$m, 'class', $shortName,
|
$m, 'class', $shortName,
|
||||||
CommentParser::$embeddedDataName
|
CommentParser::$embeddedDataName
|
||||||
) ? : array());
|
) ?: array());
|
||||||
unset(static::$instances[$name]->initPending);
|
unset(static::$instances[$name]->initPending);
|
||||||
$initialized = false;
|
$initialized = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,12 @@ namespace Luracast\Restler\UI;
|
|||||||
use Luracast\Restler\UI\Tags as T;
|
use Luracast\Restler\UI\Tags as T;
|
||||||
use Luracast\Restler\Util;
|
use Luracast\Restler\Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Emmet
|
||||||
|
* @package Luracast\Restler\UI
|
||||||
|
*
|
||||||
|
* @version 3.0.0rc6
|
||||||
|
*/
|
||||||
class Emmet
|
class Emmet
|
||||||
{
|
{
|
||||||
const DELIMITERS = '.#*>+^[=" ]{$@-#}';
|
const DELIMITERS = '.#*>+^[=" ]{$@-#}';
|
||||||
|
|||||||
@ -10,32 +10,32 @@ namespace Luracast\Restler\UI;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class FormStyles
|
class FormStyles
|
||||||
{
|
{
|
||||||
public static $html = array(
|
public static $html = array(
|
||||||
'form' => 'form[role=form id=$id# name=$name# method=$method# action=$action# enctype=$enctype#]',
|
'form' => 'form[role=form id=$id# name=$name# method=$method# action=$action# enctype=$enctype#]',
|
||||||
'input' => '.row>section>label{$label#}^input[name=$name# value=$value# type=$type# required=$required# autofocus=$autofocus# placeholder=$default# accept=$accept#]',
|
'input' => '.row>section>label{$label#}^input[id=$id# name=$name# value=$value# type=$type# required=$required# autofocus=$autofocus# placeholder=$default# accept=$accept# disabled=$disabled#]',
|
||||||
'textarea' => '.row>label{$label#}^textarea[name=$name# required=$required# autofocus=$autofocus# placeholder=$default# rows=3]{$value#}',
|
'textarea' => '.row>label{$label#}^textarea[id=$id# name=$name# required=$required# autofocus=$autofocus# placeholder=$default# rows=3 disabled=$disabled#]{$value#}',
|
||||||
'radio' => '.row>section>label{$label#}^span>label*options>input[name=$name# value=$value# type=radio checked=$selected# required=$required#]+{ $text#}',
|
'radio' => '.row>section>label{$label#}^span>label*options>input[id=$id# name=$name# value=$value# type=radio checked=$selected# required=$required# disabled=$disabled#]+{ $text#}',
|
||||||
'select' => '.row>label{$label#}^select[name=$name# required=$required#]>option[value]+option[value=$value# selected=$selected#]{$text#}*options',
|
'select' => '.row>label{$label#}^select[id=$id# name=$name# required=$required#]>option[value]+option[value=$value# selected=$selected# disabled=$disabled#]{$text#}*options',
|
||||||
'submit' => '.row>label{ }^button[type=submit]{$label#}',
|
'submit' => '.row>label{ }^button[id=$id# type=submit disabled=$disabled#]{$label#}',
|
||||||
'fieldset' => 'fieldset>legend{$label#}',
|
'fieldset' => 'fieldset>legend{$label#}',
|
||||||
'checkbox' => '.row>label>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# accept=$accept#]+{$label#}',
|
'checkbox' => '.row>label>input[id=$id# name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# accept=$accept# disabled=$disabled#]+{$label#}',
|
||||||
//------------- TYPE BASED STYLES ---------------------//
|
//------------- TYPE BASED STYLES ---------------------//
|
||||||
'checkbox-array' => 'fieldset>legend{$label#}+section*options>label>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# accept=$accept#]+{ $text#}',
|
'checkbox-array' => 'fieldset>legend{$label#}+section*options>label>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# accept=$accept#]+{ $text#}',
|
||||||
'select-array' => 'label{$label#}+select[name=$name# required=$required# multiple style="height: auto;background-image: none; outline: inherit;"]>option[value=$value# selected=$selected#]{$text#}*options',
|
'select-array' => 'label{$label#}+select[name=$name# required=$required# multiple style="height: auto;background-image: none; outline: inherit;"]>option[value=$value# selected=$selected#]{$text#}*options',
|
||||||
);
|
);
|
||||||
public static $bootstrap3 = array(
|
public static $bootstrap3 = array(
|
||||||
'form' => 'form[role=form id=$id# name=$name# method=$method# action=$action# enctype=$enctype#]',
|
'form' => 'form[role=form id=$id# name=$name# method=$method# action=$action# enctype=$enctype#]',
|
||||||
'input' => '.form-group>label{$label#}+input.form-control[name=$name# value=$value# type=$type# required=$required# autofocus=$autofocus# placeholder=$default# accept=$accept#]',
|
'input' => '.form-group.$error#>label{$label#}+input.form-control[id=$id# name=$name# value=$value# type=$type# required=$required# autofocus=$autofocus# placeholder=$default# accept=$accept# disabled=$disabled#]+small.help-block>{$message#}',
|
||||||
'textarea' => '.form-group>label{$label#}+textarea.form-control[name=$name# required=$required# autofocus=$autofocus# placeholder=$default# rows=3]{$value#}',
|
'textarea' => '.form-group>label{$label#}+textarea.form-control[id=$id# name=$name# required=$required# autofocus=$autofocus# placeholder=$default# rows=3 disabled=$disabled#]{$value#}+small.help-block>{$message#}',
|
||||||
'radio' => 'fieldset>legend{$label#}>.radio*options>label>input.radio[name=$name# value=$value# type=radio checked=$selected# required=$required#]{$text#}',
|
'radio' => 'fieldset>legend{$label#}>.radio*options>label>input.radio[name=$name# value=$value# type=radio checked=$selected# required=$required# disabled=$disabled#]{$text#}+p.help-block>{$message#}',
|
||||||
'select' => '.form-group>label{$label#}+select.form-control[name=$name# multiple=$multiple# required=$required#]>option[value]+option[value=$value# selected=$selected#]{$text#}*options',
|
'select' => '.form-group>label{$label#}+select.form-control[id=$id# name=$name# multiple=$multiple# required=$required#]>option[value]+option[value=$value# selected=$selected# disabled=$disabled#]{$text#}*options',
|
||||||
'submit' => 'button.btn.btn-primary[type=submit]{$label#}',
|
'submit' => 'button.btn.btn-primary[id=$id# type=submit]{$label#} disabled=$disabled#',
|
||||||
'fieldset' => 'fieldset>legend{$label#}',
|
'fieldset' => 'fieldset>legend{$label#}',
|
||||||
'checkbox' => '.checkbox>label>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# accept=$accept#]+{$label#}',
|
'checkbox' => '.checkbox>label>input[id=$id# name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# disabled=$disabled#]+{$label#}^p.help-block>{$error#}',
|
||||||
//------------- TYPE BASED STYLES ---------------------//
|
//------------- TYPE BASED STYLES ---------------------//
|
||||||
'checkbox-array' => 'fieldset>legend{$label#}>.checkbox*options>label>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required#]{$text#}',
|
'checkbox-array' => 'fieldset>legend{$label#}>.checkbox*options>label>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required#]{$text#}',
|
||||||
'select-array' => '.form-group>label{$label#}+select.form-control[name=$name# multiple=$multiple# required=$required#] size=$options#>option[value=$value# selected=$selected#]{$text#}*options',
|
'select-array' => '.form-group>label{$label#}+select.form-control[name=$name# multiple=$multiple# required=$required#] size=$options#>option[value=$value# selected=$selected#]{$text#}*options',
|
||||||
@ -44,15 +44,15 @@ class FormStyles
|
|||||||
);
|
);
|
||||||
public static $foundation5 = array(
|
public static $foundation5 = array(
|
||||||
'form' => 'form[id=$id# name=$name# method=$method# action=$action# enctype=$enctype#]',
|
'form' => 'form[id=$id# name=$name# method=$method# action=$action# enctype=$enctype#]',
|
||||||
'input' => 'label{$label#}+input[name=$name# value=$value# type=$type# required=$required# autofocus=$autofocus# placeholder=$default# accept=$accept#]',
|
'input' => 'label{$label#}+input[id=$id# name=$name# value=$value# type=$type# required=$required# autofocus=$autofocus# placeholder=$default# accept=$accept# disabled=$disabled#]',
|
||||||
'textarea' => 'label{$label#}+textarea[name=$name# required=$required# autofocus=$autofocus# placeholder=$default# rows=3]{$value#}',
|
'textarea' => 'label{$label#}+textarea[id=$id# name=$name# required=$required# autofocus=$autofocus# placeholder=$default# rows=3 disabled=$disabled#]{$value#}',
|
||||||
'radio' => 'label{$label# : }+label.radio-inline*options>input.radio[name=$name# value=$value# type=radio checked=$selected# required=$required#]+{$text#}',
|
'radio' => 'label{$label# : }+label.radio-inline*options>input.radio[name=$name# value=$value# type=radio checked=$selected# required=$required# disabled=$disabled#]+{$text#}',
|
||||||
'select' => 'label{$label#}+select[name=$name# required=$required#]>option[value]+option[value=$value# selected=$selected#]{$text#}*options',
|
'select' => 'label{$label#}+select[id=$id# name=$name# required=$required#]>option[value]+option[value=$value# selected=$selected# disabled=$disabled#]{$text#}*options',
|
||||||
'submit' => 'button.button[type=submit]{$label#}',
|
'submit' => 'button.button[id=$id# type=submit disabled=$disabled#]{$label#}',
|
||||||
'fieldset' => 'fieldset>legend{$label#}',
|
'fieldset' => 'fieldset>legend{$label#}',
|
||||||
'checkbox' => 'label>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# accept=$accept#]+{ $label#}',
|
'checkbox' => 'label>input[id=$id# name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# disabled=$disabled#]+{ $label#}',
|
||||||
//------------- TYPE BASED STYLES ---------------------//
|
//------------- TYPE BASED STYLES ---------------------//
|
||||||
'checkbox-array' => 'fieldset>legend{$label#}+label*options>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus# accept=$accept#]+{ $text#}',
|
'checkbox-array' => 'fieldset>legend{$label#}+label*options>input[name=$name# value=$value# type=checkbox checked=$selected# required=$required# autofocus=$autofocus#]+{ $text#}',
|
||||||
'select-array' => 'label{$label#}+select[name=$name# required=$required# multiple style="height: auto;background-image: none; outline: inherit;"]>option[value=$value# selected=$selected#]{$text#}*options',
|
'select-array' => 'label{$label#}+select[name=$name# required=$required# multiple style="height: auto;background-image: none; outline: inherit;"]>option[value=$value# selected=$selected#]{$text#}*options',
|
||||||
//------------- CUSTOM STYLES ---------------------//
|
//------------- CUSTOM STYLES ---------------------//
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,8 +3,9 @@ namespace Luracast\Restler\UI;
|
|||||||
|
|
||||||
use Luracast\Restler\CommentParser;
|
use Luracast\Restler\CommentParser;
|
||||||
use Luracast\Restler\Data\ApiMethodInfo;
|
use Luracast\Restler\Data\ApiMethodInfo;
|
||||||
use Luracast\Restler\Data\String;
|
use Luracast\Restler\Data\Text;
|
||||||
use Luracast\Restler\Data\ValidationInfo;
|
use Luracast\Restler\Data\ValidationInfo;
|
||||||
|
use Luracast\Restler\Data\Validator;
|
||||||
use Luracast\Restler\Defaults;
|
use Luracast\Restler\Defaults;
|
||||||
use Luracast\Restler\Format\UploadFormat;
|
use Luracast\Restler\Format\UploadFormat;
|
||||||
use Luracast\Restler\Format\UrlEncodedFormat;
|
use Luracast\Restler\Format\UrlEncodedFormat;
|
||||||
@ -28,7 +29,7 @@ use Luracast\Restler\Util;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Forms implements iFilter
|
class Forms implements iFilter
|
||||||
{
|
{
|
||||||
@ -190,6 +191,9 @@ class Forms implements iFilter
|
|||||||
static::$fileUpload = false;
|
static::$fileUpload = false;
|
||||||
$t['enctype'] = 'multipart/form-data';
|
$t['enctype'] = 'multipart/form-data';
|
||||||
}
|
}
|
||||||
|
if (isset($m[CommentParser::$embeddedDataName])) {
|
||||||
|
$t += $m[CommentParser::$embeddedDataName];
|
||||||
|
}
|
||||||
if (!$dataOnly) {
|
if (!$dataOnly) {
|
||||||
$t = Emmet::make(static::style('form', $m), $t);
|
$t = Emmet::make(static::style('form', $m), $t);
|
||||||
$t->prefix = $prefix;
|
$t->prefix = $prefix;
|
||||||
@ -292,14 +296,14 @@ class Forms implements iFilter
|
|||||||
$options[] = $option;
|
$options[] = $option;
|
||||||
}
|
}
|
||||||
} elseif ($p->type == 'boolean' || $p->type == 'bool') {
|
} elseif ($p->type == 'boolean' || $p->type == 'bool') {
|
||||||
if (String::beginsWith($type, 'radio')) {
|
if (Text::beginsWith($type, 'radio') || Text::beginsWith($type, 'select')) {
|
||||||
$options[] = array('name' => $p->name, 'text' => ' Yes ',
|
$options[] = array('name' => $p->name, 'text' => ' Yes ',
|
||||||
'value' => 'true');
|
'value' => 'true');
|
||||||
$options[] = array('name' => $p->name, 'text' => ' No ',
|
$options[] = array('name' => $p->name, 'text' => ' No ',
|
||||||
'value' => 'false');
|
'value' => 'false');
|
||||||
if ($p->value || $p->default)
|
if ($p->value || $p->default)
|
||||||
$options[0]['selected'] = true;
|
$options[0]['selected'] = true;
|
||||||
} else {
|
} else { //checkbox
|
||||||
$r = array(
|
$r = array(
|
||||||
'tag' => $tag,
|
'tag' => $tag,
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
@ -312,6 +316,9 @@ class Forms implements iFilter
|
|||||||
if ($p->default) {
|
if ($p->default) {
|
||||||
$r['selected'] = true;
|
$r['selected'] = true;
|
||||||
}
|
}
|
||||||
|
if (isset($p->rules)) {
|
||||||
|
$r += $p->rules;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (empty($r)) {
|
if (empty($r)) {
|
||||||
@ -325,16 +332,25 @@ class Forms implements iFilter
|
|||||||
'options' => & $options,
|
'options' => & $options,
|
||||||
'multiple' => $multiple,
|
'multiple' => $multiple,
|
||||||
);
|
);
|
||||||
|
if (isset($p->rules)) {
|
||||||
|
$r += $p->rules;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($type == 'file') {
|
if ($type == 'file') {
|
||||||
static::$fileUpload = true;
|
static::$fileUpload = true;
|
||||||
|
if (empty($r['accept'])) {
|
||||||
$r['accept'] = implode(', ', UploadFormat::$allowedMimeTypes);
|
$r['accept'] = implode(', ', UploadFormat::$allowedMimeTypes);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!empty(Validator::$exceptions[$name]) && static::$info->url == Scope::get('Restler')->url) {
|
||||||
|
$r['error'] = 'has-error';
|
||||||
|
$r['message'] = Validator::$exceptions[$p->name]->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
if (true === $p->required)
|
if (true === $p->required)
|
||||||
$r['required'] = true;
|
$r['required'] = 'required';
|
||||||
if (isset($p->rules['autofocus']))
|
if (isset($p->rules['autofocus']))
|
||||||
$r['autofocus'] = true;
|
$r['autofocus'] = 'autofocus';
|
||||||
/*
|
/*
|
||||||
echo "<pre>";
|
echo "<pre>";
|
||||||
print_r($r);
|
print_r($r);
|
||||||
@ -411,7 +427,7 @@ class Forms implements iFilter
|
|||||||
if (empty($exclude)) {
|
if (empty($exclude)) {
|
||||||
if ($url == $exclude)
|
if ($url == $exclude)
|
||||||
return true;
|
return true;
|
||||||
} elseif (String::beginsWith($url, $exclude)) {
|
} elseif (Text::beginsWith($url, $exclude)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
namespace Luracast\Restler\UI;
|
namespace Luracast\Restler\UI;
|
||||||
|
|
||||||
use Luracast\Restler\CommentParser;
|
use Luracast\Restler\CommentParser;
|
||||||
use Luracast\Restler\Defaults;
|
use Luracast\Restler\Data\Text;
|
||||||
use Luracast\Restler\Restler;
|
use Luracast\Restler\Restler;
|
||||||
use Luracast\Restler\Routes;
|
use Luracast\Restler\Routes;
|
||||||
use Luracast\Restler\Scope;
|
use Luracast\Restler\Scope;
|
||||||
@ -19,18 +19,13 @@ use Luracast\Restler\Util;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Nav
|
class Nav
|
||||||
{
|
{
|
||||||
|
protected static $tree = array();
|
||||||
public static $root = 'home';
|
public static $root = 'home';
|
||||||
/**
|
|
||||||
* @var null|callable if the api methods are under access control mechanism
|
|
||||||
* you can attach a function here that returns true or false to determine
|
|
||||||
* visibility of a protected api method. this function will receive method
|
|
||||||
* info as the only parameter.
|
|
||||||
*/
|
|
||||||
public static $accessControlFunction = null;
|
|
||||||
/**
|
/**
|
||||||
* @var array all paths beginning with any of the following will be excluded
|
* @var array all paths beginning with any of the following will be excluded
|
||||||
* from documentation. if an empty string is given it will exclude the root
|
* from documentation. if an empty string is given it will exclude the root
|
||||||
@ -40,169 +35,188 @@ class Nav
|
|||||||
* @var array prefix additional menu items with one of the following syntax
|
* @var array prefix additional menu items with one of the following syntax
|
||||||
* [$path => $text]
|
* [$path => $text]
|
||||||
* [$path]
|
* [$path]
|
||||||
* [$path => ['text' => $text, 'url' => $url]]
|
* [$path => ['text' => $text, 'url' => $url, 'trail'=> $trail]]
|
||||||
*/
|
*/
|
||||||
public static $prepends = array();
|
public static $prepends = array();
|
||||||
/**
|
/**
|
||||||
* @var array suffix additional menu items with one of the following syntax
|
* @var array suffix additional menu items with one of the following syntax
|
||||||
* [$path => $text]
|
* [$path => $text]
|
||||||
* [$path]
|
* [$path]
|
||||||
* [$path => ['text' => $text, 'url' => $url]]
|
* [$path => ['text' => $text, 'url' => $url, 'trail'=> $trail]]
|
||||||
*/
|
*/
|
||||||
public static $appends = array();
|
public static $appends = array();
|
||||||
|
|
||||||
public static $addExtension = true;
|
public static $addExtension = true;
|
||||||
|
|
||||||
protected static $extension = '';
|
protected static $extension = '';
|
||||||
|
protected static $activeTrail = '';
|
||||||
|
protected static $url;
|
||||||
|
|
||||||
public static function get($for = '', $activeUrl = null)
|
public static function get($for = '', $activeTrail = null)
|
||||||
{
|
{
|
||||||
if (!static::$accessControlFunction && Defaults::$accessControlFunction)
|
if (empty(static::$tree)) {
|
||||||
static::$accessControlFunction = Defaults::$accessControlFunction;
|
|
||||||
/** @var Restler $restler */
|
/** @var Restler $restler */
|
||||||
$restler = Scope::get('Restler');
|
$restler = Scope::get('Restler');
|
||||||
if (static::$addExtension)
|
if (static::$addExtension)
|
||||||
static::$extension = '.' . $restler->responseFormat->getExtension();
|
static::$extension = isset($restler->responseFormat)
|
||||||
if (is_null($activeUrl))
|
? '.' . $restler->responseFormat->getExtension()
|
||||||
$activeUrl = $restler->url;
|
: '.html';
|
||||||
|
static::$url = $restler->getBaseUrl();
|
||||||
$tree = array();
|
if (empty(static::$url))
|
||||||
foreach (static::$prepends as $path => $text) {
|
static::$url = '';
|
||||||
$url = null;
|
static::$activeTrail = $activeTrail = empty($activeTrail)
|
||||||
if (is_array($text)) {
|
? (empty($restler->url) || $restler->url == 'index'
|
||||||
if (isset($text['url'])) {
|
? static::$root
|
||||||
$url = $text['url'];
|
: $restler->url
|
||||||
$text = $text['text'];
|
)
|
||||||
} else {
|
: $activeTrail;
|
||||||
$url = current(array_keys($text));
|
if (static::$addExtension)
|
||||||
$text = current($text);
|
static::$extension = isset($restler->responseFormat)
|
||||||
}
|
? '.' . $restler->responseFormat->getExtension()
|
||||||
}
|
: '.html';
|
||||||
if (is_numeric($path)) {
|
static::addUrls(static::$prepends);
|
||||||
$path = $text;
|
$map = Routes::findAll(
|
||||||
$text = null;
|
static::$excludedPaths,
|
||||||
}
|
array('POST', 'DELETE', 'PUT', 'PATCH'),
|
||||||
if (empty($for) || 0 === strpos($path, "$for/"))
|
$restler->getRequestedApiVersion()
|
||||||
static::build($tree, $path, $url, $text, $activeUrl);
|
);
|
||||||
}
|
foreach ($map as $path => $data) {
|
||||||
$routes = Routes::toArray();
|
foreach ($data as $item) {
|
||||||
$routes = $routes['v' . $restler->getRequestedApiVersion()];
|
$access = $item['access'];
|
||||||
foreach ($routes as $value) {
|
$route = $item['route'];
|
||||||
foreach ($value as $httpMethod => $route) {
|
$url = $route['url'];
|
||||||
if ($httpMethod != 'GET') {
|
if ($access && !Text::contains($url, '{')) {
|
||||||
continue;
|
$label = Util::nestedValue(
|
||||||
}
|
|
||||||
$path = $route['url'];
|
|
||||||
if (false !== strpos($path, '{'))
|
|
||||||
continue;
|
|
||||||
if ($route['accessLevel'] > 1 && !Util::$restler->_authenticated)
|
|
||||||
continue;
|
|
||||||
foreach (static::$excludedPaths as $exclude) {
|
|
||||||
if (empty($exclude)) {
|
|
||||||
if (empty($path))
|
|
||||||
continue 2;
|
|
||||||
} elseif (0 === strpos($path, $exclude)) {
|
|
||||||
continue 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($restler->_authenticated
|
|
||||||
&& static::$accessControlFunction
|
|
||||||
&& (!call_user_func(
|
|
||||||
static::$accessControlFunction, $route['metadata']))
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$text = Util::nestedValue(
|
|
||||||
$route,
|
$route,
|
||||||
'metadata',
|
'metadata',
|
||||||
CommentParser::$embeddedDataName,
|
CommentParser::$embeddedDataName,
|
||||||
'label'
|
'label'
|
||||||
);
|
);
|
||||||
if (empty($for) || 0 === strpos($path, "$for/"))
|
if (!empty($url)) {
|
||||||
static::build($tree, $path, null, $text, $activeUrl);
|
$url .= static::$extension;
|
||||||
|
}
|
||||||
|
static::add($url, $label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (static::$appends as $path => $text) {
|
|
||||||
$url = null;
|
|
||||||
if (is_array($text)) {
|
|
||||||
if (isset($text['url'])) {
|
|
||||||
$url = $text['url'];
|
|
||||||
$text = $text['text'];
|
|
||||||
} else {
|
|
||||||
$url = current(array_keys($text));
|
|
||||||
$text = current($text);
|
|
||||||
}
|
}
|
||||||
|
static::addUrls(static::$appends);
|
||||||
|
} elseif (empty($activeTrail)) {
|
||||||
|
$activeTrail = static::$activeTrail;
|
||||||
}
|
}
|
||||||
if (is_numeric($path)) {
|
$tree = static::$tree;
|
||||||
$path = $text;
|
$activeTrail = explode('/', $activeTrail);
|
||||||
$text = null;
|
$nested = & static::nested($tree, $activeTrail);
|
||||||
}
|
if (is_array($nested)) {
|
||||||
if (empty($for) || 0 === strpos($path, "$for/"))
|
$nested['active'] = true;
|
||||||
static::build($tree, $path, $url, $text, $activeUrl);
|
|
||||||
}
|
}
|
||||||
if (!empty($for)) {
|
if (!empty($for)) {
|
||||||
$for = explode('/', $for);
|
$for = explode('/', $for);
|
||||||
$p = & $tree;
|
$tree = static::nested($tree, $for)['children'];
|
||||||
foreach ($for as $f) {
|
}
|
||||||
if (isset($p[$f]['children'])) {
|
return array_filter($tree);
|
||||||
$p = & $p[$f]['children'];
|
}
|
||||||
|
|
||||||
|
protected static function & nested(array & $tree, array $parts)
|
||||||
|
{
|
||||||
|
if (!empty($parts)) {
|
||||||
|
$part = array_shift($parts);
|
||||||
|
if (empty($tree[$part])) {
|
||||||
|
return $tree[$part];
|
||||||
|
} elseif (empty($parts)) {
|
||||||
|
return static::nested($tree[$part], $parts);
|
||||||
|
} elseif (!empty($tree[$part]['children'])) {
|
||||||
|
return static::nested($tree[$part]['children'], $parts);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $p;
|
|
||||||
}
|
|
||||||
return $tree;
|
return $tree;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected static function build(&$tree, $path,
|
public static function addUrls(array $urls)
|
||||||
$url = null, $text = null, $activeUrl = null)
|
|
||||||
{
|
{
|
||||||
$parts = explode('/', $path);
|
foreach ($urls as $url => $label) {
|
||||||
|
$trail = null;
|
||||||
|
if (is_array($label)) {
|
||||||
|
if (isset($label['trail'])) {
|
||||||
|
$trail = $label['trail'];
|
||||||
|
}
|
||||||
|
if (isset($label['url'])) {
|
||||||
|
$url = $label['url'];
|
||||||
|
$label = isset($label['label']) ? $label['label'] : null;
|
||||||
|
} else {
|
||||||
|
$url = current(array_keys($label));
|
||||||
|
$label = current($label);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (is_numeric($url)) {
|
||||||
|
$url = $label;
|
||||||
|
$label = null;
|
||||||
|
}
|
||||||
|
static::add($url, $label, $trail);
|
||||||
|
}
|
||||||
|
return static::$tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function add($url, $label = null, $trail = null)
|
||||||
|
{
|
||||||
|
$r = parse_url($url);
|
||||||
|
if (is_null($trail)) {
|
||||||
|
$trail = isset($r['path']) ? $r['path'] : static::$root;
|
||||||
|
}
|
||||||
|
//remove / prefix and / suffixes and any extension
|
||||||
|
$trail = strtok(trim($trail, '/'), '.');
|
||||||
|
$parts = explode('/', $trail);
|
||||||
if (count($parts) == 1 && empty($parts[0]))
|
if (count($parts) == 1 && empty($parts[0]))
|
||||||
$parts = array(static::$root);
|
$parts = array(static::$root);
|
||||||
$p = & $tree;
|
if (isset($r['fragment'])) {
|
||||||
$end = end($parts);
|
$parts[] = $r['fragment'];
|
||||||
foreach ($parts as $part) {
|
if (is_null($label)) {
|
||||||
if (!isset($p[$part])) {
|
$label = Text::title($r['fragment']);
|
||||||
$p[$part] = array(
|
}
|
||||||
'href' => '#',
|
}
|
||||||
'text' => static::title($part)
|
if (empty($r['scheme'])) {
|
||||||
);
|
//relative url found
|
||||||
if ($part == $end) {
|
if (empty($url)) {
|
||||||
$p[$part]['class'] = $part;
|
$label = Text::title(static::$root);
|
||||||
if ($text)
|
$url = static::$url;
|
||||||
$p[$part]['text'] = $text;
|
|
||||||
if (is_null($url)) {
|
|
||||||
if (empty($path) && !empty(static::$extension))
|
|
||||||
$path = 'index';
|
|
||||||
$p[$part]['href'] = Util::$restler->getBaseUrl()
|
|
||||||
. '/' . $path . static::$extension;
|
|
||||||
} else {
|
} else {
|
||||||
if (empty($url) && !empty(static::$extension))
|
$url = static::$url . '/' . ltrim($url, '/');
|
||||||
$url = 'index';
|
|
||||||
$p[$part]['href'] = $url . static::$extension;
|
|
||||||
}
|
|
||||||
if ($path == $activeUrl) {
|
|
||||||
$p[$part]['active'] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$p[$part]['children'] = array();
|
if (is_null($label)) {
|
||||||
|
$label = Text::title(strtok(end($parts), '.'));
|
||||||
|
}
|
||||||
|
$r['url'] = $url;
|
||||||
|
$r['path'] = $trail;
|
||||||
|
$r['parts'] = $parts;
|
||||||
|
$r['label'] = $label;
|
||||||
|
static::build($r);
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function build(array $r)
|
||||||
|
{
|
||||||
|
$p = & static::$tree;
|
||||||
|
$parts = $r['parts'];
|
||||||
|
$last = count($parts) - 1;
|
||||||
|
foreach ($parts as $i => $part) {
|
||||||
|
if ($i == $last) {
|
||||||
|
$p[$part]['text'] = $r['label'];
|
||||||
|
$p[$part]['href'] = $r['url'];
|
||||||
|
$p[$part]['class'] = Text::slug($part);
|
||||||
|
/* dynamically do it at run time instead
|
||||||
|
if ($r['path'] == static::$activeTrail)
|
||||||
|
$p[$part]['active'] = true;
|
||||||
|
*/
|
||||||
|
} elseif (!isset($p[$part])) {
|
||||||
|
$p[$part] = array();
|
||||||
|
$p[$part]['text'] = Text::title($part);
|
||||||
|
$p[$part]['href'] = '#';
|
||||||
|
$p[$part]['children'] = array();
|
||||||
}
|
}
|
||||||
$p = & $p[$part]['children'];
|
$p = & $p[$part]['children'];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function title($name)
|
|
||||||
{
|
|
||||||
if (empty($name)) {
|
|
||||||
$name = static::$root;
|
|
||||||
} else {
|
|
||||||
$name = ltrim($name, '#');
|
|
||||||
}
|
|
||||||
return ucfirst(preg_replace(array('/(?<=[^A-Z])([A-Z])/', '/(?<=[^0-9])([0-9])/'), ' $0', $name));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -14,7 +14,7 @@ use Luracast\Restler\Util;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*
|
*
|
||||||
* ============================ magic properties ==============================
|
* ============================ magic properties ==============================
|
||||||
* @property Tags parent parent tag
|
* @property Tags parent parent tag
|
||||||
@ -154,10 +154,10 @@ class Tags implements ArrayAccess, Countable
|
|||||||
*/
|
*/
|
||||||
public function id($value)
|
public function id($value)
|
||||||
{
|
{
|
||||||
$this->attributes['id'] = isset($value)
|
if (!empty($value) && is_string($value)) {
|
||||||
? (string)$value
|
$this->attributes['id'] = $value;
|
||||||
: Util::nestedValue($this->attributes, 'name');
|
|
||||||
static::$instances[$value] = $this;
|
static::$instances[$value] = $this;
|
||||||
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class User implements iIdentifyUser
|
class User implements iIdentifyUser
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
class Util
|
class Util
|
||||||
{
|
{
|
||||||
@ -129,6 +129,38 @@ class Util
|
|||||||
return implode($char, $fromPath);
|
return implode($char, $fromPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two strings and split the common
|
||||||
|
* sub string from the first string and return it as array
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
*
|
||||||
|
* @param string $fromPath
|
||||||
|
* @param string $usingPath
|
||||||
|
* @param string $char
|
||||||
|
* optional, set it as
|
||||||
|
* blank string for char by char comparison
|
||||||
|
*
|
||||||
|
* @return array with 2 strings first is the common string and second is the remaining in $fromPath
|
||||||
|
*/
|
||||||
|
public static function splitCommonPath($fromPath, $usingPath, $char = '/')
|
||||||
|
{
|
||||||
|
if (empty($fromPath))
|
||||||
|
return array('', '');
|
||||||
|
$fromPath = explode($char, $fromPath);
|
||||||
|
$usingPath = explode($char, $usingPath);
|
||||||
|
$commonPath = array();
|
||||||
|
while (count($usingPath)) {
|
||||||
|
if (count($fromPath) && $fromPath[0] == $usingPath[0]) {
|
||||||
|
$commonPath [] = array_shift($fromPath);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
array_shift($usingPath);
|
||||||
|
}
|
||||||
|
return array(implode($char, $commonPath), implode($char, $fromPath));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the request to figure out the http request type
|
* Parses the request to figure out the http request type
|
||||||
*
|
*
|
||||||
|
|||||||
@ -9,10 +9,6 @@
|
|||||||
{
|
{
|
||||||
"name":"Luracast",
|
"name":"Luracast",
|
||||||
"email":"arul@luracast.com"
|
"email":"arul@luracast.com"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Nick nickl- Lombard",
|
|
||||||
"email":"github@jigsoft.co.za"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"extra":{
|
"extra":{
|
||||||
@ -21,41 +17,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"suggest":{
|
"suggest":{
|
||||||
"luracast/explorer":"Restler's very own api explorer (see require-dev for details)",
|
"rodneyrehm/plist":"If you need Apple plist binary/xml format",
|
||||||
"rodneyrehm/plist":"Restler supports tho Apple plist xml format (see require-dev for details)",
|
"zendframework/zendamf":"If you need AMF format",
|
||||||
"zendframework/zendamf":"Support for the amf document format (see require-dev for details)",
|
"symfony/yaml":"If you need YAML format",
|
||||||
"symfony/yaml":"Restler can produce content in yaml format as well (see require-dev for details)",
|
"twig/twig":"If you want to use twig templates with Html format",
|
||||||
"twig/twig":"Restler can render HtmlView using twig templates (see require-dev for details)",
|
"mustache/mustache":"If you want to use mustache/handlebar templates with Html format",
|
||||||
"mustache/mustache":"Restler can render HtmlView using mustache/handlebar templates (see require-dev for details)",
|
"illuminate/view":"If you want to use laravel blade templates with Html format",
|
||||||
"bshaffer/oauth2-server-php":"Restler can provide OAuth2 authentication using this library (see require-dev for details)"
|
"bshaffer/oauth2-server-php":"If you want to use OAuth2 for authentication"
|
||||||
},
|
},
|
||||||
"require":{
|
"require":{
|
||||||
"php":">=5.3.0"
|
"php":">=5.3.0"
|
||||||
},
|
},
|
||||||
"require-dev":{
|
"require-dev":{
|
||||||
"luracast/explorer":"*",
|
|
||||||
"rodneyrehm/plist":"dev-master",
|
|
||||||
"zendframework/zendamf":"dev-master",
|
|
||||||
"symfony/yaml":"*",
|
|
||||||
"mustache/mustache": "dev-master",
|
|
||||||
"twig/twig": "v1.13.0",
|
|
||||||
"bshaffer/oauth2-server-php":"v1.0"
|
|
||||||
},
|
},
|
||||||
"repositories":[
|
"repositories":[
|
||||||
{
|
{
|
||||||
"type":"vcs",
|
"type":"vcs",
|
||||||
"url":"https://github.com/zendframework/ZendAmf.git"
|
"url":"https://github.com/zendframework/ZendAmf.git"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type":"package",
|
|
||||||
"package":{
|
|
||||||
"name":"luracast/explorer",
|
|
||||||
"version":"v3.0.0",
|
|
||||||
"dist":{
|
|
||||||
"type":"zip",
|
|
||||||
"url":"https://github.com/Luracast/Restler-API-Explorer/zipball/v3.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"autoload":{
|
"autoload":{
|
||||||
|
|||||||
@ -0,0 +1,125 @@
|
|||||||
|
/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
div,
|
||||||
|
span,
|
||||||
|
applet,
|
||||||
|
object,
|
||||||
|
iframe,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
blockquote,
|
||||||
|
pre,
|
||||||
|
a,
|
||||||
|
abbr,
|
||||||
|
acronym,
|
||||||
|
address,
|
||||||
|
big,
|
||||||
|
cite,
|
||||||
|
code,
|
||||||
|
del,
|
||||||
|
dfn,
|
||||||
|
em,
|
||||||
|
img,
|
||||||
|
ins,
|
||||||
|
kbd,
|
||||||
|
q,
|
||||||
|
s,
|
||||||
|
samp,
|
||||||
|
small,
|
||||||
|
strike,
|
||||||
|
strong,
|
||||||
|
sub,
|
||||||
|
sup,
|
||||||
|
tt,
|
||||||
|
var,
|
||||||
|
b,
|
||||||
|
u,
|
||||||
|
i,
|
||||||
|
center,
|
||||||
|
dl,
|
||||||
|
dt,
|
||||||
|
dd,
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li,
|
||||||
|
fieldset,
|
||||||
|
form,
|
||||||
|
label,
|
||||||
|
legend,
|
||||||
|
table,
|
||||||
|
caption,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
thead,
|
||||||
|
tr,
|
||||||
|
th,
|
||||||
|
td,
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
canvas,
|
||||||
|
details,
|
||||||
|
embed,
|
||||||
|
figure,
|
||||||
|
figcaption,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
output,
|
||||||
|
ruby,
|
||||||
|
section,
|
||||||
|
summary,
|
||||||
|
time,
|
||||||
|
mark,
|
||||||
|
audio,
|
||||||
|
video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
/* HTML5 display-role reset for older browsers */
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
details,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
blockquote,
|
||||||
|
q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
blockquote:before,
|
||||||
|
blockquote:after,
|
||||||
|
q:before,
|
||||||
|
q:after {
|
||||||
|
content: '';
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
@ -0,0 +1,82 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Api Explorer</title>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
|
||||||
|
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
<link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||||
|
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||||
|
<link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
|
||||||
|
<link href='css/screen.css' media='print' rel='stylesheet' type='text/css'/>
|
||||||
|
<script type="text/javascript" src="lib/shred.bundle.js"></script>
|
||||||
|
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/handlebars-1.0.0.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/underscore-min.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/backbone-min.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/swagger.js' type='text/javascript'></script>
|
||||||
|
<script src='swagger-ui.js' type='text/javascript'></script>
|
||||||
|
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
|
||||||
|
|
||||||
|
<!-- enabling this will enable oauth2 implicit scope support -->
|
||||||
|
<script src='lib/swagger-oauth.js' type='text/javascript'></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function () {
|
||||||
|
window.swaggerUi = new SwaggerUi({
|
||||||
|
url: "resources.json",
|
||||||
|
dom_id: "swagger-ui-container",
|
||||||
|
supportedSubmitMethods: ['get', 'post', 'put', 'patch', 'delete'],
|
||||||
|
onComplete: function(swaggerApi, swaggerUi){
|
||||||
|
log("Loaded Api Explorer");
|
||||||
|
|
||||||
|
if(typeof initOAuth == "function") {
|
||||||
|
/*
|
||||||
|
initOAuth({
|
||||||
|
clientId: "your-client-id",
|
||||||
|
realm: "your-realms",
|
||||||
|
appName: "your-app-name"
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
$('pre code').each(function(i, e) {
|
||||||
|
hljs.highlightBlock(e)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onFailure: function(data) {
|
||||||
|
log("Unable to Load Api Explorer");
|
||||||
|
},
|
||||||
|
docExpansion: "none"
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#input_apiKey').change(function() {
|
||||||
|
var key = $('#input_apiKey')[0].value;
|
||||||
|
log("key: " + key);
|
||||||
|
if(key && key.trim() != "") {
|
||||||
|
log("added key " + key);
|
||||||
|
window.authorizations.add("key", new ApiKeyAuthorization("api_key", key, "query"));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
window.swaggerUi.load();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="swagger-section">
|
||||||
|
<div id='header'>
|
||||||
|
<div class="swagger-ui-wrap">
|
||||||
|
<a id="logo" href="#">API Explorer</a>
|
||||||
|
<form id='api_selector'>
|
||||||
|
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="hidden" value="resources.json"/></div>
|
||||||
|
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
|
||||||
|
<div class='input'><a id="explore" href="#">Explore</a></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="message-bar" class="swagger-ui-wrap"> </div>
|
||||||
|
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
38
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js
vendored
Normal file
38
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Backbone.js 0.9.2
|
||||||
|
|
||||||
|
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||||
|
// Backbone may be freely distributed under the MIT license.
|
||||||
|
// For all details and documentation:
|
||||||
|
// http://backbonejs.org
|
||||||
|
(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks=
|
||||||
|
{});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g=
|
||||||
|
z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent=
|
||||||
|
{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null==
|
||||||
|
b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent:
|
||||||
|
b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)};
|
||||||
|
a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error,
|
||||||
|
h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t();
|
||||||
|
return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending=
|
||||||
|
{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length||
|
||||||
|
!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator);
|
||||||
|
this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++){if(!(e=a[c]=this._prepareModel(a[c],b)))throw Error("Can't add an invalid model to a collection");g=e.cid;i=e.id;j[g]||this._byCid[g]||null!=i&&(k[i]||this._byId[i])?
|
||||||
|
l.push(c):j[g]=k[i]=e}for(c=l.length;c--;)a.splice(l[c],1);c=0;for(d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=e.id&&(this._byId[e.id]=e);this.length+=d;A.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));this.comparator&&this.sort({silent:!0});if(b.silent)return this;c=0;for(d=this.models.length;c<d;c++)if(j[(e=this.models[c]).cid])b.index=c,e.trigger("add",e,this,b);return this},remove:function(a,b){var c,d,e,g;b||(b={});a=f.isArray(a)?
|
||||||
|
a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.getByCid(a[c])||this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],e=this.indexOf(g),this.models.splice(e,1),this.length--,b.silent||(b.index=e,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,b);return a},pop:function(a){var b=this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,f.extend({at:0},b));return a},
|
||||||
|
shift:function(a){var b=this.at(0);this.remove(b,a);return b},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return f.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1==this.comparator.length?
|
||||||
|
this.models=this.sortBy(b):this.models.sort(b);a.silent||this.trigger("reset",this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},reset:function(a,b){a||(a=[]);b||(b={});for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);this._reset();this.add(a,f.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d,
|
||||||
|
e,f){b[a.add?"add":"reset"](b.parse(d,f),a);c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(e,f){b.wait&&c.add(e,b);d?d(e,f):e.trigger("sync",a,f,b)};a.save(null,b);return a},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId=
|
||||||
|
{};this._byCid={}},_prepareModel:function(a,b){b||(b={});a instanceof o?a.collection||(a.collection=this):(b.collection=this,a=new this.model(a,b),a._validate(a.attributes,b)||(a=!1));return a},_removeReference:function(a){this==a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"==a||"remove"==a)&&c!=this||("destroy"==a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],this._byId[b.id]=b),this.trigger.apply(this,
|
||||||
|
arguments))}});f.each("forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split(","),function(a){r.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});var u=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},B=/:\w+/g,
|
||||||
|
C=/\*\w+/g,D=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(u.prototype,k,{initialize:function(){},route:function(a,b,c){g.history||(g.history=new m);f.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,f.bind(function(d){d=this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b)},_bindRoutes:function(){if(this.routes){var a=[],b;for(b in this.routes)a.unshift([b,
|
||||||
|
this.routes[b]]);b=0;for(var c=a.length;b<c;b++)this.route(a[b][0],a[b][1],this[a[b][1]])}},_routeToRegExp:function(a){a=a.replace(D,"\\$&").replace(B,"([^/]+)").replace(C,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});var m=g.History=function(){this.handlers=[];f.bindAll(this,"checkUrl")},s=/^[#\/]/,E=/msie [\w.]+/;m.started=!1;f.extend(m.prototype,k,{interval:50,getHash:function(a){return(a=(a?a.location:window.location).href.match(/#(.*)$/))?a[1]:
|
||||||
|
""},getFragment:function(a,b){if(null==a)if(this._hasPushState||b){var a=window.location.pathname,c=window.location.search;c&&(a+=c)}else a=this.getHash();a.indexOf(this.options.root)||(a=a.substr(this.options.root.length));return a.replace(s,"")},start:function(a){if(m.started)throw Error("Backbone.history has already been started");m.started=!0;this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=
|
||||||
|
!(!this.options.pushState||!window.history||!window.history.pushState);var a=this.getFragment(),b=document.documentMode;if(b=E.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b))this.iframe=i('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a);this._hasPushState?i(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?i(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,
|
||||||
|
this.interval));this.fragment=a;a=window.location;b=a.pathname==this.options.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),window.location.replace(this.options.root+"#"+this.fragment),!0;this._wantsPushState&&this._hasPushState&&b&&a.hash&&(this.fragment=this.getHash().replace(s,""),window.history.replaceState({},document.title,a.protocol+"//"+a.host+this.options.root+this.fragment));if(!this.options.silent)return this.loadUrl()},
|
||||||
|
stop:function(){i(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);m.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a==this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));if(a==this.fragment)return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},loadUrl:function(a){var b=this.fragment=this.getFragment(a);return f.any(this.handlers,
|
||||||
|
function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!m.started)return!1;if(!b||!0===b)b={trigger:b};var c=(a||"").replace(s,"");this.fragment!=c&&(this._hasPushState?(0!=c.indexOf(this.options.root)&&(c=this.options.root+c),this.fragment=c,window.history[b.replace?"replaceState":"pushState"]({},document.title,c)):this._wantsHashChange?(this.fragment=c,this._updateHash(window.location,c,b.replace),this.iframe&&c!=this.getFragment(this.getHash(this.iframe))&&(b.replace||
|
||||||
|
this.iframe.document.open().close(),this._updateHash(this.iframe.location,c,b.replace))):window.location.assign(this.options.root+a),b.trigger&&this.loadUrl(a))},_updateHash:function(a,b,c){c?a.replace(a.toString().replace(/(javascript:|#).*$/,"")+"#"+b):a.hash=b}});var v=g.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},F=/^(\S+)\s*(.*)$/,w="model,collection,el,id,attributes,className,tagName".split(",");
|
||||||
|
f.extend(v.prototype,k,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);b&&i(a).attr(b);c&&i(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof i?a:i(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=n(this,"events"))){this.undelegateEvents();
|
||||||
|
for(var b in a){var c=a[b];f.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(F),e=d[1],d=d[2],c=f.bind(c,this),e=e+(".delegateEvents"+this.cid);""===d?this.$el.bind(e,c):this.$el.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=0,c=w.length;b<c;b++){var d=w[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,
|
||||||
|
!1);else{var a=n(this,"attributes")||{};this.id&&(a.id=this.id);this.className&&(a["class"]=this.className);this.setElement(this.make(this.tagName,a),!1)}}});o.extend=r.extend=u.extend=v.extend=function(a,b){var c=G(this,a,b);c.extend=this.extend;return c};var H={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=H[a];c||(c={});var e={type:d,dataType:"json"};c.url||(e.url=n(b,"url")||t());if(!c.data&&b&&("create"==a||"update"==a))e.contentType="application/json",
|
||||||
|
e.data=JSON.stringify(b.toJSON());g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);return i.ajax(f.extend(e,c))};g.wrapError=function(a,b,c){return function(d,e){e=d===b?e:d;a?a(b,e,c):b.trigger("error",b,e,c)}};var x=function(){},G=function(a,
|
||||||
|
b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){a.apply(this,arguments)};f.extend(d,a);x.prototype=a.prototype;d.prototype=new x;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},n=function(a,b){return!a||!a[b]?null:f.isFunction(a[b])?a[b]():a[b]},t=function(){throw Error('A "url" property or function must be specified');}}).call(this);
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
2
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery-1.8.0.min.js
vendored
Normal file
2
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery-1.8.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
18
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery.ba-bbq.min.js
vendored
Normal file
18
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery.ba-bbq.min.js
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
|
||||||
|
* http://benalman.com/projects/jquery-bbq-plugin/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||||
|
* Dual licensed under the MIT and GPL licenses.
|
||||||
|
* http://benalman.com/about/license/
|
||||||
|
*/
|
||||||
|
(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
|
||||||
|
/*
|
||||||
|
* jQuery hashchange event - v1.2 - 2/11/2010
|
||||||
|
* http://benalman.com/projects/jquery-hashchange-plugin/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||||
|
* Dual licensed under the MIT and GPL licenses.
|
||||||
|
* http://benalman.com/about/license/
|
||||||
|
*/
|
||||||
|
(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this);
|
||||||
1
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery.slideto.min.js
vendored
Normal file
1
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery.slideto.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(b){b.fn.slideto=function(a){a=b.extend({slide_duration:"slow",highlight_duration:3E3,highlight:true,highlight_color:"#FFFF99"},a);return this.each(function(){obj=b(this);b("body").animate({scrollTop:obj.offset().top},a.slide_duration,function(){a.highlight&&b.ui.version&&obj.effect("highlight",{color:a.highlight_color},a.highlight_duration)})})}})(jQuery);
|
||||||
8
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery.wiggle.min.js
vendored
Normal file
8
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jquery.wiggle.min.js
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
jQuery Wiggle
|
||||||
|
Author: WonderGroup, Jordan Thomas
|
||||||
|
URL: http://labs.wondergroup.com/demos/mini-ui/index.html
|
||||||
|
License: MIT (http://en.wikipedia.org/wiki/MIT_License)
|
||||||
|
*/
|
||||||
|
jQuery.fn.wiggle=function(o){var d={speed:50,wiggles:3,travel:5,callback:null};var o=jQuery.extend(d,o);return this.each(function(){var cache=this;var wrap=jQuery(this).wrap('<div class="wiggle-wrap"></div>').css("position","relative");var calls=0;for(i=1;i<=o.wiggles;i++){jQuery(this).animate({left:"-="+o.travel},o.speed).animate({left:"+="+o.travel*2},o.speed*2).animate({left:"-="+o.travel},o.speed,function(){calls++;if(jQuery(cache).parent().hasClass('wiggle-wrap')){jQuery(cache).parent().replaceWith(cache);}
|
||||||
|
if(calls==o.wiggles&&jQuery.isFunction(o.callback)){o.callback();}});}});};
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,193 @@
|
|||||||
|
|
||||||
|
// The purpose of the `Content` object is to abstract away the data conversions
|
||||||
|
// to and from raw content entities as strings. For example, you want to be able
|
||||||
|
// to pass in a Javascript object and have it be automatically converted into a
|
||||||
|
// JSON string if the `content-type` is set to a JSON-based media type.
|
||||||
|
// Conversely, you want to be able to transparently get back a Javascript object
|
||||||
|
// in the response if the `content-type` is a JSON-based media-type.
|
||||||
|
|
||||||
|
// One limitation of the current implementation is that it [assumes the `charset` is UTF-8](https://github.com/spire-io/shred/issues/5).
|
||||||
|
|
||||||
|
// The `Content` constructor takes an options object, which *must* have either a
|
||||||
|
// `body` or `data` property and *may* have a `type` property indicating the
|
||||||
|
// media type. If there is no `type` attribute, a default will be inferred.
|
||||||
|
var Content = function(options) {
|
||||||
|
this.body = options.body;
|
||||||
|
this.data = options.data;
|
||||||
|
this.type = options.type;
|
||||||
|
};
|
||||||
|
|
||||||
|
Content.prototype = {
|
||||||
|
// Treat `toString()` as asking for the `content.body`. That is, the raw content entity.
|
||||||
|
//
|
||||||
|
// toString: function() { return this.body; }
|
||||||
|
//
|
||||||
|
// Commented out, but I've forgotten why. :/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// `Content` objects have the following attributes:
|
||||||
|
Object.defineProperties(Content.prototype,{
|
||||||
|
|
||||||
|
// - **type**. Typically accessed as `content.type`, reflects the `content-type`
|
||||||
|
// header associated with the request or response. If not passed as an options
|
||||||
|
// to the constructor or set explicitly, it will infer the type the `data`
|
||||||
|
// attribute, if possible, and, failing that, will default to `text/plain`.
|
||||||
|
type: {
|
||||||
|
get: function() {
|
||||||
|
if (this._type) {
|
||||||
|
return this._type;
|
||||||
|
} else {
|
||||||
|
if (this._data) {
|
||||||
|
switch(typeof this._data) {
|
||||||
|
case "string": return "text/plain";
|
||||||
|
case "object": return "application/json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "text/plain";
|
||||||
|
},
|
||||||
|
set: function(value) {
|
||||||
|
this._type = value;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
enumerable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// - **data**. Typically accessed as `content.data`, reflects the content entity
|
||||||
|
// converted into Javascript data. This can be a string, if the `type` is, say,
|
||||||
|
// `text/plain`, but can also be a Javascript object. The conversion applied is
|
||||||
|
// based on the `processor` attribute. The `data` attribute can also be set
|
||||||
|
// directly, in which case the conversion will be done the other way, to infer
|
||||||
|
// the `body` attribute.
|
||||||
|
data: {
|
||||||
|
get: function() {
|
||||||
|
if (this._body) {
|
||||||
|
return this.processor.parser(this._body);
|
||||||
|
} else {
|
||||||
|
return this._data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: function(data) {
|
||||||
|
if (this._body&&data) Errors.setDataWithBody(this);
|
||||||
|
this._data = data;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
enumerable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// - **body**. Typically accessed as `content.body`, reflects the content entity
|
||||||
|
// as a UTF-8 string. It is the mirror of the `data` attribute. If you set the
|
||||||
|
// `data` attribute, the `body` attribute will be inferred and vice-versa. If
|
||||||
|
// you attempt to set both, an exception is raised.
|
||||||
|
body: {
|
||||||
|
get: function() {
|
||||||
|
if (this._data) {
|
||||||
|
return this.processor.stringify(this._data);
|
||||||
|
} else {
|
||||||
|
return this._body.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: function(body) {
|
||||||
|
if (this._data&&body) Errors.setBodyWithData(this);
|
||||||
|
this._body = body;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
enumerable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// - **processor**. The functions that will be used to convert to/from `data` and
|
||||||
|
// `body` attributes. You can add processors. The two that are built-in are for
|
||||||
|
// `text/plain`, which is basically an identity transformation and
|
||||||
|
// `application/json` and other JSON-based media types (including custom media
|
||||||
|
// types with `+json`). You can add your own processors. See below.
|
||||||
|
processor: {
|
||||||
|
get: function() {
|
||||||
|
var processor = Content.processors[this.type];
|
||||||
|
if (processor) {
|
||||||
|
return processor;
|
||||||
|
} else {
|
||||||
|
// Return the first processor that matches any part of the
|
||||||
|
// content type. ex: application/vnd.foobar.baz+json will match json.
|
||||||
|
var main = this.type.split(";")[0];
|
||||||
|
var parts = main.split(/\+|\//);
|
||||||
|
for (var i=0, l=parts.length; i < l; i++) {
|
||||||
|
processor = Content.processors[parts[i]]
|
||||||
|
}
|
||||||
|
return processor || {parser:identity,stringify:toString};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumerable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// - **length**. Typically accessed as `content.length`, returns the length in
|
||||||
|
// bytes of the raw content entity.
|
||||||
|
length: {
|
||||||
|
get: function() {
|
||||||
|
if (typeof Buffer !== 'undefined') {
|
||||||
|
return Buffer.byteLength(this.body);
|
||||||
|
}
|
||||||
|
return this.body.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Content.processors = {};
|
||||||
|
|
||||||
|
// The `registerProcessor` function allows you to add your own processors to
|
||||||
|
// convert content entities. Each processor consists of a Javascript object with
|
||||||
|
// two properties:
|
||||||
|
// - **parser**. The function used to parse a raw content entity and convert it
|
||||||
|
// into a Javascript data type.
|
||||||
|
// - **stringify**. The function used to convert a Javascript data type into a
|
||||||
|
// raw content entity.
|
||||||
|
Content.registerProcessor = function(types,processor) {
|
||||||
|
|
||||||
|
// You can pass an array of types that will trigger this processor, or just one.
|
||||||
|
// We determine the array via duck-typing here.
|
||||||
|
if (types.forEach) {
|
||||||
|
types.forEach(function(type) {
|
||||||
|
Content.processors[type] = processor;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If you didn't pass an array, we just use what you pass in.
|
||||||
|
Content.processors[types] = processor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the identity processor, which is used for text-based media types.
|
||||||
|
var identity = function(x) { return x; }
|
||||||
|
, toString = function(x) { return x.toString(); }
|
||||||
|
Content.registerProcessor(
|
||||||
|
["text/html","text/plain","text"],
|
||||||
|
{ parser: identity, stringify: toString });
|
||||||
|
|
||||||
|
// Register the JSON processor, which is used for JSON-based media types.
|
||||||
|
Content.registerProcessor(
|
||||||
|
["application/json; charset=utf-8","application/json","json"],
|
||||||
|
{
|
||||||
|
parser: function(string) {
|
||||||
|
return JSON.parse(string);
|
||||||
|
},
|
||||||
|
stringify: function(data) {
|
||||||
|
return JSON.stringify(data); }});
|
||||||
|
|
||||||
|
var qs = require('querystring');
|
||||||
|
// Register the post processor, which is used for JSON-based media types.
|
||||||
|
Content.registerProcessor(
|
||||||
|
["application/x-www-form-urlencoded"],
|
||||||
|
{ parser : qs.parse, stringify : qs.stringify });
|
||||||
|
|
||||||
|
// Error functions are defined separately here in an attempt to make the code
|
||||||
|
// easier to read.
|
||||||
|
var Errors = {
|
||||||
|
setDataWithBody: function(object) {
|
||||||
|
throw new Error("Attempt to set data attribute of a content object " +
|
||||||
|
"when the body attributes was already set.");
|
||||||
|
},
|
||||||
|
setBodyWithData: function(object) {
|
||||||
|
throw new Error("Attempt to set body attribute of a content object " +
|
||||||
|
"when the data attributes was already set.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = Content;
|
||||||
@ -0,0 +1,218 @@
|
|||||||
|
var appName;
|
||||||
|
var popupMask;
|
||||||
|
var popupDialog;
|
||||||
|
var clientId;
|
||||||
|
var realm;
|
||||||
|
|
||||||
|
function handleLogin() {
|
||||||
|
var scopes = [];
|
||||||
|
|
||||||
|
if(window.swaggerUi.api.authSchemes
|
||||||
|
&& window.swaggerUi.api.authSchemes.oauth2
|
||||||
|
&& window.swaggerUi.api.authSchemes.oauth2.scopes) {
|
||||||
|
scopes = window.swaggerUi.api.authSchemes.oauth2.scopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(window.swaggerUi.api
|
||||||
|
&& window.swaggerUi.api.info) {
|
||||||
|
appName = window.swaggerUi.api.info.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(popupDialog.length > 0)
|
||||||
|
popupDialog = popupDialog.last();
|
||||||
|
else {
|
||||||
|
popupDialog = $(
|
||||||
|
[
|
||||||
|
'<div class="api-popup-dialog">',
|
||||||
|
'<div class="api-popup-title">Select OAuth2.0 Scopes</div>',
|
||||||
|
'<div class="api-popup-content">',
|
||||||
|
'<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.',
|
||||||
|
'<a href="#">Learn how to use</a>',
|
||||||
|
'</p>',
|
||||||
|
'<p><strong>' + appName + '</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>',
|
||||||
|
'<ul class="api-popup-scopes">',
|
||||||
|
'</ul>',
|
||||||
|
'<p class="error-msg"></p>',
|
||||||
|
'<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button">Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',
|
||||||
|
'</div>',
|
||||||
|
'</div>'].join(''));
|
||||||
|
$(document.body).append(popupDialog);
|
||||||
|
|
||||||
|
popup = popupDialog.find('ul.api-popup-scopes').empty();
|
||||||
|
for (i = 0; i < scopes.length; i ++) {
|
||||||
|
scope = scopes[i];
|
||||||
|
str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"/>' + '<label for="scope_' + i + '">' + scope.scope;
|
||||||
|
if (scope.description) {
|
||||||
|
str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
|
||||||
|
}
|
||||||
|
str += '</label></li>';
|
||||||
|
popup.append(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var $win = $(window),
|
||||||
|
dw = $win.width(),
|
||||||
|
dh = $win.height(),
|
||||||
|
st = $win.scrollTop(),
|
||||||
|
dlgWd = popupDialog.outerWidth(),
|
||||||
|
dlgHt = popupDialog.outerHeight(),
|
||||||
|
top = (dh -dlgHt)/2 + st,
|
||||||
|
left = (dw - dlgWd)/2;
|
||||||
|
|
||||||
|
popupDialog.css({
|
||||||
|
top: (top < 0? 0 : top) + 'px',
|
||||||
|
left: (left < 0? 0 : left) + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
popupDialog.find('button.api-popup-cancel').click(function() {
|
||||||
|
popupMask.hide();
|
||||||
|
popupDialog.hide();
|
||||||
|
});
|
||||||
|
popupDialog.find('button.api-popup-authbtn').click(function() {
|
||||||
|
popupMask.hide();
|
||||||
|
popupDialog.hide();
|
||||||
|
|
||||||
|
var authSchemes = window.swaggerUi.api.authSchemes;
|
||||||
|
var location = window.location;
|
||||||
|
var locationUrl = location.protocol + '//' + location.host + location.pathname;
|
||||||
|
var redirectUrl = locationUrl.replace("index.html","").concat("/o2c.html").replace("//o2c.html","/o2c.html");
|
||||||
|
var url = null;
|
||||||
|
|
||||||
|
var p = window.swaggerUi.api.authSchemes;
|
||||||
|
for (var key in p) {
|
||||||
|
if (p.hasOwnProperty(key)) {
|
||||||
|
var o = p[key].grantTypes;
|
||||||
|
for(var t in o) {
|
||||||
|
if(o.hasOwnProperty(t) && t === 'implicit') {
|
||||||
|
var dets = o[t];
|
||||||
|
url = dets.loginEndpoint.url + "?response_type=token";
|
||||||
|
window.swaggerUi.tokenName = dets.tokenName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var scopes = [];
|
||||||
|
var scopeForUrl='';
|
||||||
|
var o = $('.api-popup-scopes').find('input:checked');
|
||||||
|
|
||||||
|
for(var k =0; k < o.length; k++) {
|
||||||
|
scopes.push($(o[k]).attr("scope"));
|
||||||
|
if(k > 0){
|
||||||
|
scopeForUrl+=' ';
|
||||||
|
}
|
||||||
|
scopeForUrl+=$(o[k]).attr("scope");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.enabledScopes=scopes;
|
||||||
|
|
||||||
|
|
||||||
|
url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
|
||||||
|
url += '&realm=' + encodeURIComponent(realm);
|
||||||
|
url += '&client_id=' + encodeURIComponent(clientId);
|
||||||
|
url += '&scope=' + encodeURIComponent(scopeForUrl);
|
||||||
|
|
||||||
|
window.open(url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
popupMask.show();
|
||||||
|
popupDialog.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleLogout() {
|
||||||
|
for(key in window.authorizations.authz){
|
||||||
|
window.authorizations.remove(key)
|
||||||
|
}
|
||||||
|
window.enabledScopes = null;
|
||||||
|
$('.api-ic.ic-on').addClass('ic-off');
|
||||||
|
$('.api-ic.ic-on').removeClass('ic-on');
|
||||||
|
|
||||||
|
// set the info box
|
||||||
|
$('.api-ic.ic-warning').addClass('ic-error');
|
||||||
|
$('.api-ic.ic-warning').removeClass('ic-warning');
|
||||||
|
}
|
||||||
|
|
||||||
|
function initOAuth(opts) {
|
||||||
|
var o = (opts||{});
|
||||||
|
var errors = [];
|
||||||
|
|
||||||
|
appName = (o.appName||errors.push("missing appName"));
|
||||||
|
popupMask = (o.popupMask||$('#api-common-mask'));
|
||||||
|
popupDialog = (o.popupDialog||$('.api-popup-dialog'));
|
||||||
|
clientId = (o.clientId||errors.push("missing client id"));
|
||||||
|
realm = (o.realm||errors.push("missing realm"));
|
||||||
|
|
||||||
|
if(errors.length > 0){
|
||||||
|
log("auth unable initialize oauth: " + errors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
|
||||||
|
$('.api-ic').click(function(s) {
|
||||||
|
if($(s.target).hasClass('ic-off'))
|
||||||
|
handleLogin();
|
||||||
|
else {
|
||||||
|
handleLogout();
|
||||||
|
}
|
||||||
|
false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOAuthComplete(token) {
|
||||||
|
if(token) {
|
||||||
|
if(token.error) {
|
||||||
|
var checkbox = $('input[type=checkbox],.secured')
|
||||||
|
checkbox.each(function(pos){
|
||||||
|
checkbox[pos].checked = false;
|
||||||
|
});
|
||||||
|
alert(token.error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var b = token[window.swaggerUi.tokenName];
|
||||||
|
if(b){
|
||||||
|
// if all roles are satisfied
|
||||||
|
var o = null;
|
||||||
|
$.each($('.auth #api_information_panel'), function(k, v) {
|
||||||
|
var children = v;
|
||||||
|
if(children && children.childNodes) {
|
||||||
|
var requiredScopes = [];
|
||||||
|
$.each((children.childNodes), function (k1, v1){
|
||||||
|
var inner = v1.innerHTML;
|
||||||
|
if(inner)
|
||||||
|
requiredScopes.push(inner);
|
||||||
|
});
|
||||||
|
var diff = [];
|
||||||
|
for(var i=0; i < requiredScopes.length; i++) {
|
||||||
|
var s = requiredScopes[i];
|
||||||
|
if(window.enabledScopes && window.enabledScopes.indexOf(s) == -1) {
|
||||||
|
diff.push(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(diff.length > 0){
|
||||||
|
o = v.parentNode;
|
||||||
|
$(o.parentNode).find('.api-ic.ic-on').addClass('ic-off');
|
||||||
|
$(o.parentNode).find('.api-ic.ic-on').removeClass('ic-on');
|
||||||
|
|
||||||
|
// sorry, not all scopes are satisfied
|
||||||
|
$(o).find('.api-ic').addClass('ic-warning');
|
||||||
|
$(o).find('.api-ic').removeClass('ic-error');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
o = v.parentNode;
|
||||||
|
$(o.parentNode).find('.api-ic.ic-off').addClass('ic-on');
|
||||||
|
$(o.parentNode).find('.api-ic.ic-off').removeClass('ic-off');
|
||||||
|
|
||||||
|
// all scopes are satisfied
|
||||||
|
$(o).find('.api-ic').addClass('ic-info');
|
||||||
|
$(o).find('.api-ic').removeClass('ic-warning');
|
||||||
|
$(o).find('.api-ic').removeClass('ic-error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.authorizations.add("key", new ApiKeyAuthorization("Authorization", "Bearer " + b, "header"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
32
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/underscore-min.js
vendored
Normal file
32
htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/underscore-min.js
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Underscore.js 1.3.3
|
||||||
|
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||||
|
// Underscore is freely distributable under the MIT license.
|
||||||
|
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||||
|
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||||
|
// For all details and documentation:
|
||||||
|
// http://documentcloud.github.com/underscore
|
||||||
|
(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
|
||||||
|
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
|
||||||
|
g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,
|
||||||
|
c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===o)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===o)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.map===z)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(A&&
|
||||||
|
a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
|
||||||
|
c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
|
||||||
|
a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
|
||||||
|
function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&
|
||||||
|
(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){d=Math.floor(Math.random()*(f+1));b[f]=b[d];b[d]=a});return b};b.sortBy=function(a,c,d){var e=b.isFunction(c)?c:function(a){return a[c]};return b.pluck(b.map(a,function(a,b,c){return{value:a,criteria:e.call(d,a,b,c)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
|
||||||
|
j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};b.first=b.head=b.take=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,
|
||||||
|
0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,
|
||||||
|
e=[];a.length<3&&(c=true);b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
|
||||||
|
i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(q&&a.indexOf===q)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(F&&a.lastIndexOf===F)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){if(arguments.length<=
|
||||||
|
1){b=a||0;a=0}for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+d}return g};var H=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));H.prototype=a.prototype;var b=new H,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=
|
||||||
|
i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(null,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h=
|
||||||
|
g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));g?h=true:i=a.apply(d,e);j();g=true;return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments;d&&!e&&a.apply(f,g);clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));
|
||||||
|
return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
|
||||||
|
c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
|
||||||
|
function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
|
||||||
|
b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
|
||||||
|
b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
|
||||||
|
function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
|
||||||
|
u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
|
||||||
|
b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
|
||||||
|
this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
<script>
|
||||||
|
var qp = null;
|
||||||
|
if(window.location.hash) {
|
||||||
|
qp = location.hash.substring(1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qp = location.search.substring(1);
|
||||||
|
}
|
||||||
|
qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}',
|
||||||
|
function(key, value) {
|
||||||
|
return key===""?value:decodeURIComponent(value) }
|
||||||
|
):{}
|
||||||
|
window.opener.onOAuthComplete(qp);
|
||||||
|
window.close();
|
||||||
|
</script>
|
||||||
File diff suppressed because it is too large
Load Diff
1
htdocs/includes/restler/framework/Luracast/Restler/explorer/swagger-ui.min.js
vendored
Normal file
1
htdocs/includes/restler/framework/Luracast/Restler/explorer/swagger-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -11,7 +11,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iAuthenticate extends iFilter
|
interface iAuthenticate extends iFilter
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iCache
|
interface iCache
|
||||||
{
|
{
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use Exception;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iCompose {
|
interface iCompose {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iFilter
|
interface iFilter
|
||||||
{
|
{
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iIdentifyUser
|
interface iIdentifyUser
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,8 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Luracast\Restler;
|
namespace Luracast\Restler;
|
||||||
|
|
||||||
|
/**
|
||||||
interface iProvideMultiVersionApi {
|
* Interface iProvideMultiVersionApi
|
||||||
|
* @package Luracast\Restler
|
||||||
|
*
|
||||||
|
* @version 3.0.0rc6
|
||||||
|
*/
|
||||||
|
interface iProvideMultiVersionApi
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Maximum api version supported by the api class
|
* Maximum api version supported by the api class
|
||||||
* @return int
|
* @return int
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Luracast\Restler;
|
|||||||
* @copyright 2010 Luracast
|
* @copyright 2010 Luracast
|
||||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||||
* @link http://luracast.com/products/restler/
|
* @link http://luracast.com/products/restler/
|
||||||
* @version 3.0.0rc5
|
* @version 3.0.0rc6
|
||||||
*/
|
*/
|
||||||
interface iUseAuthentication
|
interface iUseAuthentication
|
||||||
{
|
{
|
||||||
|
|||||||
@ -64,7 +64,7 @@ if ($success && isset($api)) {
|
|||||||
} else {
|
} else {
|
||||||
if (isset($response['error']['message'])) {
|
if (isset($response['error']['message'])) {
|
||||||
$icon = '<icon class="denied"></icon>';
|
$icon = '<icon class="denied"></icon>';
|
||||||
$title = end(explode(':',$response['error']['message']));
|
$title = end(explode(':',$response['error']['message'],2));
|
||||||
} else {
|
} else {
|
||||||
$icon = '<icon class="warning"></icon>';
|
$icon = '<icon class="warning"></icon>';
|
||||||
$title = 'No Matching Resource';
|
$title = 'No Matching Resource';
|
||||||
|
|||||||
@ -438,6 +438,7 @@ ALTER TABLE llx_resource ADD COLUMN extraparams varchar(255);
|
|||||||
|
|
||||||
ALTER TABLE llx_element_resources ADD COLUMN duree real; -- total duration of using ressource
|
ALTER TABLE llx_element_resources ADD COLUMN duree real; -- total duration of using ressource
|
||||||
|
|
||||||
|
UPDATE llx_element_resources SET resource_type = 'dolresource' WHERE resource_type = 'resource';
|
||||||
|
|
||||||
CREATE TABLE llx_advtargetemailing
|
CREATE TABLE llx_advtargetemailing
|
||||||
(
|
(
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
# Dolibarr language file - Source file is en_US - other
|
# Dolibarr language file - Source file is en_US - other
|
||||||
SecurityCode=Security code
|
SecurityCode=Security code
|
||||||
Calendar=Calendar
|
Calendar=Calendar
|
||||||
|
NumberingShort=N°
|
||||||
Tools=Tools
|
Tools=Tools
|
||||||
ToolsDesc=This area is dedicated to group miscellaneous tools not available into other menu entries.<br><br>Those tools can be reached from menu on the side.
|
ToolsDesc=This area is dedicated to group miscellaneous tools not available into other menu entries.<br><br>Those tools can be reached from menu on the side.
|
||||||
Birthday=Birthday
|
Birthday=Birthday
|
||||||
|
|||||||
@ -563,7 +563,11 @@ if (! defined('NOLOGIN'))
|
|||||||
$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action); // Note that $action and $object may have been modified by some hooks
|
$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action); // Note that $action and $object may have been modified by some hooks
|
||||||
if ($reshook < 0) $error++;
|
if ($reshook < 0) $error++;
|
||||||
|
|
||||||
header('Location: '.DOL_URL_ROOT.'/index.php');
|
$paramsurl=array();
|
||||||
|
if (GETPOST('textbrowser')) $paramsurl[]='textbrowser='.GETPOST('textbrowser','int');
|
||||||
|
if (GETPOST('nojs')) $paramsurl[]='nojs='.GETPOST('nojs','int');
|
||||||
|
if (GETPOST('lang')) $paramsurl[]='lang='.GETPOST('lang','alpha');
|
||||||
|
header('Location: '.DOL_URL_ROOT.'/index.php'.($count(paramsurl)?'?'.join('&',$paramsurl):''));
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,7 +621,11 @@ if (! defined('NOLOGIN'))
|
|||||||
$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action); // Note that $action and $object may have been modified by some hooks
|
$reshook=$hookmanager->executeHooks('afterLoginFailed',$parameters,$user,$action); // Note that $action and $object may have been modified by some hooks
|
||||||
if ($reshook < 0) $error++;
|
if ($reshook < 0) $error++;
|
||||||
|
|
||||||
header('Location: '.DOL_URL_ROOT.'/index.php');
|
$paramsurl=array();
|
||||||
|
if (GETPOST('textbrowser')) $paramsurl[]='textbrowser='.GETPOST('textbrowser','int');
|
||||||
|
if (GETPOST('nojs')) $paramsurl[]='nojs='.GETPOST('nojs','int');
|
||||||
|
if (GETPOST('lang')) $paramsurl[]='lang='.GETPOST('lang','alpha');
|
||||||
|
header('Location: '.DOL_URL_ROOT.'/index.php'.($count(paramsurl)?'?'.join('&',$paramsurl):''));
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -756,6 +764,11 @@ if (! GETPOST('nojs')) // If javascript was not disabled on URL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else $conf->use_javascript_ajax=0;
|
else $conf->use_javascript_ajax=0;
|
||||||
|
// Set MAIN_OPTIMIZEFORTEXTBROWSER
|
||||||
|
if (GETPOST('textbrowser') || ! empty($user->conf->MAIN_OPTIMIZEFORTEXTBROWSER)) // If text browser was enabled on URL
|
||||||
|
{
|
||||||
|
$conf->global->MAIN_OPTIMIZEFORTEXTBROWSER=1;
|
||||||
|
}
|
||||||
|
|
||||||
// Set terminal output option according to conf->browser.
|
// Set terminal output option according to conf->browser.
|
||||||
if (GETPOST('dol_hide_leftmenu') || ! empty($_SESSION['dol_hide_leftmenu'])) $conf->dol_hide_leftmenu=1;
|
if (GETPOST('dol_hide_leftmenu') || ! empty($_SESSION['dol_hide_leftmenu'])) $conf->dol_hide_leftmenu=1;
|
||||||
@ -1006,9 +1019,9 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs
|
|||||||
$favicon=dol_buildpath('/theme/'.$conf->theme.'/img/favicon.ico',1);
|
$favicon=dol_buildpath('/theme/'.$conf->theme.'/img/favicon.ico',1);
|
||||||
if (! empty($conf->global->MAIN_FAVICON_URL)) $favicon=$conf->global->MAIN_FAVICON_URL;
|
if (! empty($conf->global->MAIN_FAVICON_URL)) $favicon=$conf->global->MAIN_FAVICON_URL;
|
||||||
print '<link rel="shortcut icon" type="image/x-icon" href="'.$favicon.'"/>'."\n";
|
print '<link rel="shortcut icon" type="image/x-icon" href="'.$favicon.'"/>'."\n";
|
||||||
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="top" title="'.$langs->trans("Home").'" href="'.(DOL_URL_ROOT?DOL_URL_ROOT:'/').'">'."\n";
|
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && ! GETPOST('textbrowser')) print '<link rel="top" title="'.$langs->trans("Home").'" href="'.(DOL_URL_ROOT?DOL_URL_ROOT:'/').'">'."\n";
|
||||||
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="copyright" title="GNU General Public License" href="http://www.gnu.org/copyleft/gpl.html#SEC1">'."\n";
|
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && ! GETPOST('textbrowser')) print '<link rel="copyright" title="GNU General Public License" href="http://www.gnu.org/copyleft/gpl.html#SEC1">'."\n";
|
||||||
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="author" title="Dolibarr Development Team" href="http://www.dolibarr.org">'."\n";
|
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && ! GETPOST('textbrowser')) print '<link rel="author" title="Dolibarr Development Team" href="http://www.dolibarr.org">'."\n";
|
||||||
|
|
||||||
// Displays title
|
// Displays title
|
||||||
$appli=constant('DOL_APPLICATION_TITLE');
|
$appli=constant('DOL_APPLICATION_TITLE');
|
||||||
@ -1460,7 +1473,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a
|
|||||||
else $toprightmenu.=$result; // For backward compatibility
|
else $toprightmenu.=$result; // For backward compatibility
|
||||||
|
|
||||||
// Link to print main content area
|
// Link to print main content area
|
||||||
if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->browser->phone))
|
if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && empty($conf->browser->phone))
|
||||||
{
|
{
|
||||||
$qs=$_SERVER["QUERY_STRING"];
|
$qs=$_SERVER["QUERY_STRING"];
|
||||||
$qs.=(($qs && $morequerystring)?'&':'').$morequerystring;
|
$qs.=(($qs && $morequerystring)?'&':'').$morequerystring;
|
||||||
@ -1471,7 +1484,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Link to Dolibarr wiki pages
|
// Link to Dolibarr wiki pages
|
||||||
if (empty($conf->global->MAIN_HELP_DISABLELINK))
|
if (empty($conf->global->MAIN_HELP_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
|
||||||
{
|
{
|
||||||
$langs->load("help");
|
$langs->load("help");
|
||||||
|
|
||||||
|
|||||||
@ -1435,7 +1435,7 @@ else
|
|||||||
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
|
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
|
||||||
print $langs->trans("BarcodeType");
|
print $langs->trans("BarcodeType");
|
||||||
print '</td>';
|
print '</td>';
|
||||||
if (($action != 'editbarcodetype') && ! empty($user->rights->barcode->creer)) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbarcodetype&id='.$object->id.'">'.img_edit($langs->trans('Edit'),1).'</a></td>';
|
if (($action != 'editbarcodetype') && ! empty($user->rights->produit->creer) && $createbarcode) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbarcodetype&id='.$object->id.'">'.img_edit($langs->trans('Edit'),1).'</a></td>';
|
||||||
print '</tr></table>';
|
print '</tr></table>';
|
||||||
print '</td><td colspan="2">';
|
print '</td><td colspan="2">';
|
||||||
if ($action == 'editbarcodetype')
|
if ($action == 'editbarcodetype')
|
||||||
@ -1456,7 +1456,7 @@ else
|
|||||||
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
|
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
|
||||||
print $langs->trans("BarcodeValue");
|
print $langs->trans("BarcodeValue");
|
||||||
print '</td>';
|
print '</td>';
|
||||||
if (($action != 'editbarcode') && ! empty($user->rights->barcode->creer)) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbarcode&id='.$object->id.'">'.img_edit($langs->trans('Edit'),1).'</a></td>';
|
if (($action != 'editbarcode') && ! empty($user->rights->produit->creer) && $createbarcode) print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbarcode&id='.$object->id.'">'.img_edit($langs->trans('Edit'),1).'</a></td>';
|
||||||
print '</tr></table>';
|
print '</tr></table>';
|
||||||
print '</td><td colspan="2">';
|
print '</td><td colspan="2">';
|
||||||
if ($action == 'editbarcode')
|
if ($action == 'editbarcode')
|
||||||
|
|||||||
@ -30,7 +30,7 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php";
|
|||||||
*/
|
*/
|
||||||
class Dolresource extends CommonObject
|
class Dolresource extends CommonObject
|
||||||
{
|
{
|
||||||
var $element='resource'; //!< Id that identify managed objects
|
var $element='dolresource'; //!< Id that identify managed objects
|
||||||
var $table_element='resource'; //!< Name of table without prefix where object is stored
|
var $table_element='resource'; //!< Name of table without prefix where object is stored
|
||||||
|
|
||||||
var $resource_id;
|
var $resource_id;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user