Ajout projet webAduc

This commit is contained in:
2020-11-20 13:56:16 +01:00
parent 6161dbe38f
commit 1c2b707ce8
141 changed files with 11677 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,146 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jstree basic demos</title>
<style>
html { margin:0; padding:0; font-size:62.5%; }
body { max-width:800px; min-width:300px; margin:0 auto; padding:20px 10px; font-size:14px; font-size:1.4em; }
h1 { font-size:1.8em; }
.demo { overflow:auto; border:1px solid silver; min-height:100px; }
</style>
<link rel="stylesheet" href="./../../dist/themes/default/style.min.css" />
</head>
<body>
<h1>HTML demo</h1>
<div id="html" class="demo">
<ul>
<li data-jstree='{ "opened" : true }'>Root node
<ul>
<li data-jstree='{ "selected" : true }'>Child node 1</li>
<li>Child node 2</li>
</ul>
</li>
</ul>
</div>
<h1>Inline data demo</h1>
<div id="data" class="demo"></div>
<h1>Data format demo</h1>
<div id="frmt" class="demo"></div>
<h1>AJAX demo</h1>
<div id="ajax" class="demo"></div>
<h1>Lazy loading demo</h1>
<div id="lazy" class="demo"></div>
<h1>Callback function data demo</h1>
<div id="clbk" class="demo"></div>
<h1>Interaction and events demo</h1>
<button id="evts_button">select node with id 1</button> <em>either click the button or a node in the tree</em>
<div id="evts" class="demo"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="./../../dist/jstree.min.js"></script>
<script>
// html demo
$('#html').jstree();
// inline data demo
$('#data').jstree({
'core' : {
'data' : [
{ "text" : "Root node", "children" : [
{ "text" : "Child node 1" },
{ "text" : "Child node 2" }
]}
]
}
});
// data format demo
$('#frmt').jstree({
'core' : {
'data' : [
{
"text" : "Root node",
"state" : { "opened" : true },
"children" : [
{
"text" : "Child node 1",
"state" : { "selected" : true },
"icon" : "jstree-file"
},
{ "text" : "Child node 2", "state" : { "disabled" : true } }
]
}
]
}
});
// ajax demo
$('#ajax').jstree({
'core' : {
'data' : {
"url" : "./root.json",
"dataType" : "json" // needed only if you do not supply JSON headers
}
}
});
// lazy demo
$('#lazy').jstree({
'core' : {
'data' : {
"url" : "//www.jstree.com/fiddle/?lazy",
"data" : function (node) {
return { "id" : node.id };
}
}
}
});
// data from callback
$('#clbk').jstree({
'core' : {
'data' : function (node, cb) {
if(node.id === "#") {
cb([{"text" : "Root", "id" : "1", "children" : true}]);
}
else {
cb(["Child"]);
}
}
}
});
// interaction and events
$('#evts_button').on("click", function () {
var instance = $('#evts').jstree(true);
instance.deselect_all();
instance.select_node('1');
});
$('#evts')
.on("changed.jstree", function (e, data) {
if(data.selected.length) {
alert('The selected node is: ' + data.instance.get_node(data.selected[0]).text);
}
})
.jstree({
'core' : {
'multiple' : false,
'data' : [
{ "text" : "Root node", "children" : [
{ "text" : "Child node 1", "id" : 1 },
{ "text" : "Child node 2" }
]}
]
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1 @@
[{"id":1,"text":"Root node","children":[{"id":2,"text":"Child node 1"},{"id":3,"text":"Child node 2"}]}]

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

View File

@@ -0,0 +1,19 @@
{
"name": "snoel/phpaduc",
"description": "Web manager for samba AD domain",
"type": "project",
"license": "GNU/Gpl",
"authors": [{
"name": "Serge NOEL",
"email": "serge.noel@net6a.com"
}],
"require": {
"php": "7.*",
"components/jquery": "3.*",
"components/jqueryui": "1.*",
"vakata/jstree": "3.*",
"twbs/bootstrap": "4.*",
"smarty/smarty": "3.*",
"adldap2/adldap2": "10.*"
}
}

858
Sources/webAduc/www/composer.lock generated Normal file
View File

@@ -0,0 +1,858 @@
{
"_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#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7e3aa01c6b3577f1bd7b3c4f03e0093a",
"packages": [
{
"name": "adldap2/adldap2",
"version": "v10.3.1",
"source": {
"type": "git",
"url": "https://github.com/Adldap2/Adldap2.git",
"reference": "936a4e2eb925d005198f716a75bb78068c4de94d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Adldap2/Adldap2/zipball/936a4e2eb925d005198f716a75bb78068c4de94d",
"reference": "936a4e2eb925d005198f716a75bb78068c4de94d",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-ldap": "*",
"illuminate/contracts": "~5.0|~6.0|~7.0|~8.0",
"php": ">=7.0",
"psr/log": "~1.0",
"psr/simple-cache": "~1.0",
"tightenco/collect": "~5.0|~6.0|~7.0|~8.0"
},
"require-dev": {
"mockery/mockery": "~1.0",
"phpunit/phpunit": "~6.0|~7.0|~8.0"
},
"suggest": {
"ext-fileinfo": "fileinfo is required when retrieving user encoded thumbnails"
},
"type": "library",
"autoload": {
"psr-4": {
"Adldap\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Steve Bauman",
"email": "steven_bauman@outlook.com",
"role": "Developer"
}
],
"description": "A PHP LDAP Package for humans.",
"keywords": [
"active directory",
"ad",
"adLDAP",
"adldap2",
"directory",
"ldap",
"windows"
],
"time": "2020-09-09T12:55:51+00:00"
},
{
"name": "components/jquery",
"version": "3.5.1",
"source": {
"type": "git",
"url": "https://github.com/components/jquery.git",
"reference": "b33e8f0f9a1cb2ae390cf05d766a900b53d2125b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/components/jquery/zipball/b33e8f0f9a1cb2ae390cf05d766a900b53d2125b",
"reference": "b33e8f0f9a1cb2ae390cf05d766a900b53d2125b",
"shasum": ""
},
"type": "component",
"extra": {
"component": {
"scripts": [
"jquery.js"
],
"files": [
"jquery.min.js",
"jquery.min.map",
"jquery.slim.js",
"jquery.slim.min.js",
"jquery.slim.min.map"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "JS Foundation and other contributors"
}
],
"description": "jQuery JavaScript Library",
"homepage": "http://jquery.com",
"time": "2020-05-05T13:21:02+00:00"
},
{
"name": "components/jqueryui",
"version": "1.12.1",
"source": {
"type": "git",
"url": "https://github.com/components/jqueryui.git",
"reference": "44ecf3794cc56b65954cc19737234a3119d036cc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/components/jqueryui/zipball/44ecf3794cc56b65954cc19737234a3119d036cc",
"reference": "44ecf3794cc56b65954cc19737234a3119d036cc",
"shasum": ""
},
"require": {
"components/jquery": ">=1.6"
},
"type": "component",
"extra": {
"component": {
"name": "jquery-ui",
"scripts": [
"jquery-ui.js"
],
"files": [
"ui/**",
"themes/**",
"jquery-ui.min.js"
],
"shim": {
"deps": [
"jquery"
],
"exports": "jQuery"
}
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "jQuery UI Team",
"homepage": "http://jqueryui.com/about"
},
{
"name": "Joern Zaefferer",
"email": "joern.zaefferer@gmail.com",
"homepage": "http://bassistance.de"
},
{
"name": "Scott Gonzalez",
"email": "scott.gonzalez@gmail.com",
"homepage": "http://scottgonzalez.com"
},
{
"name": "Kris Borchers",
"email": "kris.borchers@gmail.com",
"homepage": "http://krisborchers.com"
},
{
"name": "Mike Sherov",
"email": "mike.sherov@gmail.com",
"homepage": "http://mike.sherov.com"
},
{
"name": "TJ VanToll",
"email": "tj.vantoll@gmail.com",
"homepage": "http://tjvantoll.com"
},
{
"name": "Corey Frang",
"email": "gnarf37@gmail.com",
"homepage": "http://gnarf.net"
},
{
"name": "Felix Nagel",
"email": "info@felixnagel.com",
"homepage": "http://www.felixnagel.com"
}
],
"description": "jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library. Whether you're building highly interactive web applications or you just need to add a date picker to a form control, jQuery UI is the perfect choice.",
"time": "2016-09-16T05:47:55+00:00"
},
{
"name": "illuminate/contracts",
"version": "v8.15.0",
"source": {
"type": "git",
"url": "https://github.com/illuminate/contracts.git",
"reference": "d9e6a156efb8332dcce427b7d1ccd2706609bfa5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/d9e6a156efb8332dcce427b7d1ccd2706609bfa5",
"reference": "d9e6a156efb8332dcce427b7d1ccd2706609bfa5",
"shasum": ""
},
"require": {
"php": "^7.3|^8.0",
"psr/container": "^1.0",
"psr/simple-cache": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.x-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Contracts\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Contracts package.",
"homepage": "https://laravel.com",
"time": "2020-11-10T15:48:45+00:00"
},
{
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/log",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2020-03-23T09:12:05+00:00"
},
{
"name": "psr/simple-cache",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/simple-cache.git",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\SimpleCache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interfaces for simple caching",
"keywords": [
"cache",
"caching",
"psr",
"psr-16",
"simple-cache"
],
"time": "2017-10-23T01:57:42+00:00"
},
{
"name": "smarty/smarty",
"version": "v3.1.36",
"source": {
"type": "git",
"url": "https://github.com/smarty-php/smarty.git",
"reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/fd148f7ade295014fff77f89ee3d5b20d9d55451",
"reference": "fd148f7ade295014fff77f89ee3d5b20d9d55451",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"require-dev": {
"phpunit/phpunit": "6.4.1",
"smarty/smarty-lexer": "^3.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1.x-dev"
}
},
"autoload": {
"classmap": [
"libs/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Monte Ohrt",
"email": "monte@ohrt.com"
},
{
"name": "Uwe Tews",
"email": "uwe.tews@googlemail.com"
},
{
"name": "Rodney Rehm",
"email": "rodney.rehm@medialize.de"
}
],
"description": "Smarty - the compiling PHP template engine",
"homepage": "http://www.smarty.net",
"keywords": [
"templating"
],
"time": "2020-04-14T14:44:26+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v5.1.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "4e13f3fcefb1fcaaa5efb5403581406f4e840b9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/4e13f3fcefb1fcaaa5efb5403581406f4e840b9a",
"reference": "4e13f3fcefb1fcaaa5efb5403581406f4e840b9a",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.15"
},
"conflict": {
"phpunit/phpunit": "<5.4.3",
"symfony/console": "<4.4"
},
"require-dev": {
"ext-iconv": "*",
"symfony/console": "^4.4|^5.0",
"symfony/process": "^4.4|^5.0",
"twig/twig": "^2.4|^3.0"
},
"suggest": {
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
"ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
},
"bin": [
"Resources/bin/var-dump-server"
],
"type": "library",
"autoload": {
"files": [
"Resources/functions/dump.php"
],
"psr-4": {
"Symfony\\Component\\VarDumper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony mechanism for exploring and dumping PHP variables",
"homepage": "https://symfony.com",
"keywords": [
"debug",
"dump"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-27T10:11:13+00:00"
},
{
"name": "tightenco/collect",
"version": "v8.14.0",
"source": {
"type": "git",
"url": "https://github.com/tighten/collect.git",
"reference": "8f79c602c872afd7c9371e193d6aa4ed13e97661"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tighten/collect/zipball/8f79c602c872afd7c9371e193d6aa4ed13e97661",
"reference": "8f79c602c872afd7c9371e193d6aa4ed13e97661",
"shasum": ""
},
"require": {
"php": "^7.2",
"symfony/var-dumper": "^3.4 || ^4.0 || ^5.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"nesbot/carbon": "^2.23.0",
"phpunit/phpunit": "^8.3"
},
"type": "library",
"autoload": {
"files": [
"src/Collect/Support/helpers.php",
"src/Collect/Support/alias.php"
],
"psr-4": {
"Tightenco\\Collect\\": "src/Collect"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylorotwell@gmail.com"
}
],
"description": "Collect - Illuminate Collections as a separate package.",
"keywords": [
"collection",
"laravel"
],
"time": "2020-11-16T18:55:11+00:00"
},
{
"name": "twbs/bootstrap",
"version": "v4.5.3",
"source": {
"type": "git",
"url": "https://github.com/twbs/bootstrap.git",
"reference": "a716fb03f965dc0846df479e14388b1b4b93d7ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twbs/bootstrap/zipball/a716fb03f965dc0846df479e14388b1b4b93d7ce",
"reference": "a716fb03f965dc0846df479e14388b1b4b93d7ce",
"shasum": ""
},
"replace": {
"twitter/bootstrap": "self.version"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Otto",
"email": "markdotto@gmail.com"
},
{
"name": "Jacob Thornton",
"email": "jacobthornton@gmail.com"
}
],
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"homepage": "https://getbootstrap.com/",
"keywords": [
"JS",
"css",
"framework",
"front-end",
"mobile-first",
"responsive",
"sass",
"web"
],
"funding": [
{
"url": "https://opencollective.com/bootstrap",
"type": "open_collective"
}
],
"time": "2020-10-13T15:38:30+00:00"
},
{
"name": "vakata/jstree",
"version": "3.3.10",
"source": {
"type": "git",
"url": "https://github.com/vakata/jstree.git",
"reference": "6dce2271757dd0bd4cd0e941bd093c6678e98faf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vakata/jstree/zipball/6dce2271757dd0bd4cd0e941bd093c6678e98faf",
"reference": "6dce2271757dd0bd4cd0e941bd093c6678e98faf",
"shasum": ""
},
"require": {
"components/jquery": ">=1.9.1"
},
"suggest": {
"robloach/component-installer": "Allows installation of Components via Composer"
},
"type": "component",
"extra": {
"component": {
"scripts": [
"dist/jstree.js"
],
"styles": [
"dist/themes/default/style.css"
],
"images": [
"dist/themes/default/32px.png",
"dist/themes/default/40px.png",
"dist/themes/default/throbber.gif"
],
"files": [
"dist/jstree.min.js",
"dist/themes/default/style.min.css",
"dist/themes/default/32px.png",
"dist/themes/default/40px.png",
"dist/themes/default/throbber.gif"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ivan Bozhanov",
"email": "jstree@jstree.com"
}
],
"description": "jsTree is jquery plugin, that provides interactive trees.",
"homepage": "http://jstree.com",
"time": "2020-06-16T11:17:46+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "7.*"
},
"platform-dev": [],
"plugin-api-version": "1.1.0"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1 @@
deny from all

View File

@@ -0,0 +1 @@
Conteneur

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,450 @@
<?php
ini_set('open_basedir', dirname(__FILE__) . DIRECTORY_SEPARATOR);
class fs
{
protected $base = null;
protected function real($path) {
$temp = realpath($path);
if(!$temp) { throw new Exception('Path does not exist: ' . $path); }
if($this->base && strlen($this->base)) {
if(strpos($temp, $this->base) !== 0) { throw new Exception('Path is not inside base ('.$this->base.'): ' . $temp); }
}
return $temp;
}
protected function path($id) {
$id = str_replace('/', DIRECTORY_SEPARATOR, $id);
$id = trim($id, DIRECTORY_SEPARATOR);
$id = $this->real($this->base . DIRECTORY_SEPARATOR . $id);
return $id;
}
protected function id($path) {
$path = $this->real($path);
$path = substr($path, strlen($this->base));
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
$path = trim($path, '/');
return strlen($path) ? $path : '/';
}
public function __construct($base) {
$this->base = $this->real($base);
if(!$this->base) { throw new Exception('Base directory does not exist'); }
}
public function lst($id, $with_root = false) {
$dir = $this->path($id);
$lst = @scandir($dir);
if(!$lst) { throw new Exception('Could not list path: ' . $dir); }
$res = array();
foreach($lst as $item) {
if($item == '.' || $item == '..' || $item === null) { continue; }
$tmp = preg_match('([^ a-zа-я-_0-9.]+)ui', $item);
if($tmp === false || $tmp === 1) { continue; }
if(is_dir($dir . DIRECTORY_SEPARATOR . $item)) {
$res[] = array('text' => $item, 'children' => true, 'id' => $this->id($dir . DIRECTORY_SEPARATOR . $item), 'icon' => 'folder');
}
else {
$res[] = array('text' => $item, 'children' => false, 'id' => $this->id($dir . DIRECTORY_SEPARATOR . $item), 'type' => 'file', 'icon' => 'file file-'.substr($item, strrpos($item,'.') + 1));
}
}
if($with_root && $this->id($dir) === '/') {
$res = array(array('text' => basename($this->base), 'children' => $res, 'id' => '/', 'icon'=>'folder', 'state' => array('opened' => true, 'disabled' => true)));
}
return $res;
}
public function data($id) {
if(strpos($id, ":")) {
$id = array_map(array($this, 'id'), explode(':', $id));
return array('type'=>'multiple', 'content'=> 'Multiple selected: ' . implode(' ', $id));
}
$dir = $this->path($id);
if(is_dir($dir)) {
return array('type'=>'folder', 'content'=> $id);
}
if(is_file($dir)) {
$ext = strpos($dir, '.') !== FALSE ? substr($dir, strrpos($dir, '.') + 1) : '';
$dat = array('type' => $ext, 'content' => '');
switch($ext) {
case 'txt':
case 'text':
case 'md':
case 'js':
case 'json':
case 'css':
case 'html':
case 'htm':
case 'xml':
case 'c':
case 'cpp':
case 'h':
case 'sql':
case 'log':
case 'py':
case 'rb':
case 'htaccess':
case 'php':
$dat['content'] = file_get_contents($dir);
break;
case 'jpg':
case 'jpeg':
case 'gif':
case 'png':
case 'bmp':
$dat['content'] = 'data:'.finfo_file(finfo_open(FILEINFO_MIME_TYPE), $dir).';base64,'.base64_encode(file_get_contents($dir));
break;
default:
$dat['content'] = 'File not recognized: '.$this->id($dir);
break;
}
return $dat;
}
throw new Exception('Not a valid selection: ' . $dir);
}
public function create($id, $name, $mkdir = false) {
$dir = $this->path($id);
if(preg_match('([^ a-zа-я-_0-9.]+)ui', $name) || !strlen($name)) {
throw new Exception('Invalid name: ' . $name);
}
if($mkdir) {
mkdir($dir . DIRECTORY_SEPARATOR . $name);
}
else {
file_put_contents($dir . DIRECTORY_SEPARATOR . $name, '');
}
return array('id' => $this->id($dir . DIRECTORY_SEPARATOR . $name));
}
public function rename($id, $name) {
$dir = $this->path($id);
if($dir === $this->base) {
throw new Exception('Cannot rename root');
}
if(preg_match('([^ a-zа-я-_0-9.]+)ui', $name) || !strlen($name)) {
throw new Exception('Invalid name: ' . $name);
}
$new = explode(DIRECTORY_SEPARATOR, $dir);
array_pop($new);
array_push($new, $name);
$new = implode(DIRECTORY_SEPARATOR, $new);
if($dir !== $new) {
if(is_file($new) || is_dir($new)) { throw new Exception('Path already exists: ' . $new); }
rename($dir, $new);
}
return array('id' => $this->id($new));
}
public function remove($id) {
$dir = $this->path($id);
if($dir === $this->base) {
throw new Exception('Cannot remove root');
}
if(is_dir($dir)) {
foreach(array_diff(scandir($dir), array(".", "..")) as $f) {
$this->remove($this->id($dir . DIRECTORY_SEPARATOR . $f));
}
rmdir($dir);
}
if(is_file($dir)) {
unlink($dir);
}
return array('status' => 'OK');
}
public function move($id, $par) {
$dir = $this->path($id);
$par = $this->path($par);
$new = explode(DIRECTORY_SEPARATOR, $dir);
$new = array_pop($new);
$new = $par . DIRECTORY_SEPARATOR . $new;
rename($dir, $new);
return array('id' => $this->id($new));
}
public function copy($id, $par) {
$dir = $this->path($id);
$par = $this->path($par);
$new = explode(DIRECTORY_SEPARATOR, $dir);
$new = array_pop($new);
$new = $par . DIRECTORY_SEPARATOR . $new;
if(is_file($new) || is_dir($new)) { throw new Exception('Path already exists: ' . $new); }
if(is_dir($dir)) {
mkdir($new);
foreach(array_diff(scandir($dir), array(".", "..")) as $f) {
$this->copy($this->id($dir . DIRECTORY_SEPARATOR . $f), $this->id($new));
}
}
if(is_file($dir)) {
copy($dir, $new);
}
return array('id' => $this->id($new));
}
}
if(isset($_GET['operation'])) {
$fs = new fs(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'root' . DIRECTORY_SEPARATOR);
try {
$rslt = null;
switch($_GET['operation']) {
case 'get_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->lst($node, (isset($_GET['id']) && $_GET['id'] === '#'));
break;
case "get_content":
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->data($node);
break;
case 'create_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->create($node, isset($_GET['text']) ? $_GET['text'] : '', (!isset($_GET['type']) || $_GET['type'] !== 'file'));
break;
case 'rename_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->rename($node, isset($_GET['text']) ? $_GET['text'] : '');
break;
case 'delete_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$rslt = $fs->remove($node);
break;
case 'move_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$parn = isset($_GET['parent']) && $_GET['parent'] !== '#' ? $_GET['parent'] : '/';
$rslt = $fs->move($node, $parn);
break;
case 'copy_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : '/';
$parn = isset($_GET['parent']) && $_GET['parent'] !== '#' ? $_GET['parent'] : '/';
$rslt = $fs->copy($node, $parn);
break;
default:
throw new Exception('Unsupported operation: ' . $_GET['operation']);
break;
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode($rslt);
}
catch (Exception $e) {
header($_SERVER["SERVER_PROTOCOL"] . ' 500 Server Error');
header('Status: 500 Server Error');
echo $e->getMessage();
}
die();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Title</title>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="../vendor/vakata/jstree/dist/themes/default/style.min.css" />
<style>
html, body { background:#ebebeb; font-size:10px; font-family:Verdana; margin:0; padding:0; }
#container { min-width:320px; margin:0px auto 0 auto; background:white; border-radius:0px; padding:0px; overflow:hidden; }
#tree { float:left; min-width:319px; border-right:1px solid silver; overflow:auto; padding:0px 0; }
#data { margin-left:320px; }
#data textarea { margin:0; padding:0; height:100%; width:100%; border:0; background:white; display:block; line-height:18px; resize:none; }
#data, #code { font: normal normal normal 12px/18px 'Consolas', monospace !important; }
#tree .folder { background:url('./file_sprite.png') right bottom no-repeat; }
#tree .file { background:url('./file_sprite.png') 0 0 no-repeat; }
#tree .file-pdf { background-position: -32px 0 }
#tree .file-as { background-position: -36px 0 }
#tree .file-c { background-position: -72px -0px }
#tree .file-iso { background-position: -108px -0px }
#tree .file-htm, #tree .file-html, #tree .file-xml, #tree .file-xsl { background-position: -126px -0px }
#tree .file-cf { background-position: -162px -0px }
#tree .file-cpp { background-position: -216px -0px }
#tree .file-cs { background-position: -236px -0px }
#tree .file-sql { background-position: -272px -0px }
#tree .file-xls, #tree .file-xlsx { background-position: -362px -0px }
#tree .file-h { background-position: -488px -0px }
#tree .file-crt, #tree .file-pem, #tree .file-cer { background-position: -452px -18px }
#tree .file-php { background-position: -108px -18px }
#tree .file-jpg, #tree .file-jpeg, #tree .file-png, #tree .file-gif, #tree .file-bmp { background-position: -126px -18px }
#tree .file-ppt, #tree .file-pptx { background-position: -144px -18px }
#tree .file-rb { background-position: -180px -18px }
#tree .file-text, #tree .file-txt, #tree .file-md, #tree .file-log, #tree .file-htaccess { background-position: -254px -18px }
#tree .file-doc, #tree .file-docx { background-position: -362px -18px }
#tree .file-zip, #tree .file-gz, #tree .file-tar, #tree .file-rar { background-position: -416px -18px }
#tree .file-js { background-position: -434px -18px }
#tree .file-css { background-position: -144px -0px }
#tree .file-fla { background-position: -398px -0px }
</style>
</head>
<body>
<div id="container" role="main">
<div id="tree"></div>
<div id="data">
<div class="content code" style="display:none;"><textarea id="code" readonly="readonly"></textarea></div>
<div class="content folder" style="display:none;"></div>
<div class="content image" style="display:none; position:relative;"><img src="" alt="" style="display:block; position:absolute; left:50%; top:50%; padding:0; max-height:90%; max-width:90%;" /></div>
<div class="content default" style="text-align:center;">Select a file from the tree.</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="../vendor/vakata/jstree/dist/jstree.min.js"></script>
<script>
$(function () {
$(window).resize(function () {
var h = Math.max($(window).height() - 0, 420);
$('#container, #data, #tree, #data .content').height(h).filter('.default').css('lineHeight', h + 'px');
}).resize();
$('#tree')
.jstree({
'core' : {
'data' : {
'url' : '?operation=get_node',
'data' : function (node) {
return { 'id' : node.id };
}
},
'check_callback' : function(o, n, p, i, m) {
if(m && m.dnd && m.pos !== 'i') { return false; }
if(o === "move_node" || o === "copy_node") {
if(this.get_node(n).parent === this.get_node(p).id) { return false; }
}
return true;
},
'force_text' : true,
'themes' : {
'responsive' : false,
'variant' : 'small',
'stripes' : true
}
},
'sort' : function(a, b) {
return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : (this.get_type(a) >= this.get_type(b) ? 1 : -1);
},
'contextmenu' : {
'items' : function(node) {
var tmp = $.jstree.defaults.contextmenu.items();
delete tmp.create.action;
tmp.create.label = "New";
tmp.create.submenu = {
"create_folder" : {
"separator_after" : true,
"label" : "Folder",
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.create_node(obj, { type : "default" }, "last", function (new_node) {
setTimeout(function () { inst.edit(new_node); },0);
});
}
},
"create_file" : {
"label" : "File",
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.create_node(obj, { type : "file" }, "last", function (new_node) {
setTimeout(function () { inst.edit(new_node); },0);
});
}
}
};
if(this.get_type(node) === "file") {
delete tmp.create;
}
return tmp;
}
},
'types' : {
'default' : { 'icon' : 'folder' },
'file' : { 'valid_children' : [], 'icon' : 'file' }
},
'unique' : {
'duplicate' : function (name, counter) {
return name + ' ' + counter;
}
},
'plugins' : ['state','dnd','sort','types','contextmenu','unique']
})
.on('delete_node.jstree', function (e, data) {
$.get('?operation=delete_node', { 'id' : data.node.id })
.fail(function () {
data.instance.refresh();
});
})
.on('create_node.jstree', function (e, data) {
$.get('?operation=create_node', { 'type' : data.node.type, 'id' : data.node.parent, 'text' : data.node.text })
.done(function (d) {
data.instance.set_id(data.node, d.id);
})
.fail(function () {
data.instance.refresh();
});
})
.on('rename_node.jstree', function (e, data) {
$.get('?operation=rename_node', { 'id' : data.node.id, 'text' : data.text })
.done(function (d) {
data.instance.set_id(data.node, d.id);
})
.fail(function () {
data.instance.refresh();
});
})
.on('move_node.jstree', function (e, data) {
$.get('?operation=move_node', { 'id' : data.node.id, 'parent' : data.parent })
.done(function (d) {
//data.instance.load_node(data.parent);
data.instance.refresh();
})
.fail(function () {
data.instance.refresh();
});
})
.on('copy_node.jstree', function (e, data) {
$.get('?operation=copy_node', { 'id' : data.original.id, 'parent' : data.parent })
.done(function (d) {
//data.instance.load_node(data.parent);
data.instance.refresh();
})
.fail(function () {
data.instance.refresh();
});
})
.on('changed.jstree', function (e, data) {
if(data && data.selected && data.selected.length) {
$.get('?operation=get_content&id=' + data.selected.join(':'), function (d) {
if(d && typeof d.type !== 'undefined') {
$('#data .content').hide();
switch(d.type) {
case 'text':
case 'txt':
case 'md':
case 'htaccess':
case 'log':
case 'sql':
case 'php':
case 'js':
case 'json':
case 'css':
case 'html':
$('#data .code').show();
$('#code').val(d.content);
break;
case 'png':
case 'jpg':
case 'jpeg':
case 'bmp':
case 'gif':
$('#data .image img').one('load', function () { $(this).css({'marginTop':'-' + $(this).height()/2 + 'px','marginLeft':'-' + $(this).width()/2 + 'px'}); }).attr('src',d.content);
$('#data .image').show();
break;
default:
$('#data .default').html(d.content).show();
break;
}
}
});
}
else {
$('#data .content').hide();
$('#data .default').html('Select a file from the tree.').show();
}
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,90 @@
<?php
/**
* This file is the entry point of phpAduc.
*
* Ce fichier redirige les demandes vers la page appropriée
*
* PHP version > 7.3
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Main
* @package phpAduc
* @author Serge NOEL <serge.noel@easylinux.fr>
* @copyright 2016-2020 Easylinux
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version GIT: 2.0
* @link ../tests/Documentation Tests/Documentation.odt
*/
// Charge les classes installées par Composer
require_once 'vendor/autoload.php';
// Lire la configuration du site
require_once 'src/config/config.php';
require_once 'src/class/autoload.php';
session_start();
/* Initialisation de Smarty */
$smarty = new Smarty();
// Définir le dossier templates
$smarty->setTemplateDir('src/templates');
$smarty->setConfigDir('src/templates/configs');
// Définir le dossier qui recoit les templates compilés
$smarty->setCompileDir('templates_c');
$smarty->setCacheDir('src/templates_c/cache');
// Lire la page demandée
$Action=filter_input(INPUT_POST,'Action',FILTER_SANITIZE_STRING);
if(!isset($_SESSION['Loggued']) && $Action=="")
{
$Action='Login';
}
error_log("Appel avec $Action");
switch($Action)
{
case 'tryLogin':
error_log('tryLogin ');
$Usr=new userClass();
$sLogin=filter_input(INPUT_POST,'sLogin',FILTER_SANITIZE_STRING);
$sPasswd=filter_input(INPUT_POST,'sPassword',FILTER_SANITIZE_STRING);
if($Usr->isValid($sLogin,$sPasswd))
{
$template='main.smarty';
$component='main';
$_SESSION['loggued']=true;
}
else
{
$template='login.smarty';
$component="";
$smarty->assign('error','Compte ou mot de passe invalide !');
$smarty->assign('Title',"easyCloud");
}
break;
case 'Logout':
unset($_SESSION['Loggued']);
case 'Login':
$template='login.smarty';
$component="";
break;
default:
$component=strtolower($Action);
$template="$component.smarty";
break;
}
if($component!="")
{
require_once("src/components/$component.php");
}
$smarty->assign('Title',"easyCloud");
echo $smarty->display($template);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
$(document).ready(function(){
$('input[type=password]').keyup(function() {
var pswd = $(this).val();
//validate the length
if ( pswd.length < 8 ) {
$('#length').removeClass('valid').addClass('invalid');
} else {
$('#length').removeClass('invalid').addClass('valid');
}
//validate letter
if ( pswd.match(/[A-z]/) ) {
$('#letter').removeClass('invalid').addClass('valid');
} else {
$('#letter').removeClass('valid').addClass('invalid');
}
//validate capital letter
if ( pswd.match(/[A-Z]/) ) {
$('#capital').removeClass('invalid').addClass('valid');
} else {
$('#capital').removeClass('valid').addClass('invalid');
}
//validate number
if ( pswd.match(/\d/) ) {
$('#number').removeClass('invalid').addClass('valid');
} else {
$('#number').removeClass('valid').addClass('invalid');
}
//validate space
if ( pswd.match(/[^a-zA-Z0-9\-\/]/) ) {
$('#space').removeClass('invalid').addClass('valid');
} else {
$('#space').removeClass('valid').addClass('invalid');
}
}).focus(function() {
$('#pswd_info').show();
}).blur(function() {
$('#pswd_info').hide();
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M2115 5099 c-16 -5 -124 -35 -240 -65 -115 -31 -215 -60 -222 -66 -7
-5 -17 -7 -23 -3 -17 11 -12 -21 30 -175 22 -81 40 -155 40 -165 0 -11 -26
-28 -77 -52 -43 -20 -80 -39 -83 -42 -3 -4 -20 -13 -38 -20 -18 -8 -87 -50
-155 -95 -109 -72 -175 -110 -154 -90 4 4 -48 63 -115 131 l-123 123 -207
-207 -208 -208 125 -125 c69 -69 125 -128 125 -131 0 -3 -36 -59 -79 -124 -44
-66 -77 -123 -75 -127 3 -4 1 -8 -3 -8 -9 0 -50 -76 -51 -94 0 -5 -4 -12 -9
-15 -5 -3 -21 -33 -36 -66 -20 -45 -31 -59 -44 -57 -10 2 -83 21 -163 43 -80
21 -153 39 -162 39 -9 0 -18 -11 -21 -27 -3 -16 -35 -140 -72 -276 -37 -136
-65 -250 -62 -253 2 -3 82 -26 176 -51 l171 -46 -8 -41 c-9 -53 -9 -438 1
-492 7 -44 5 -47 -64 -60 -42 -8 -271 -73 -276 -78 -5 -5 135 -544 144 -555 4
-5 87 14 245 58 l106 29 58 -119 c32 -65 62 -119 67 -119 4 0 6 -4 3 -8 -2 -4
31 -61 75 -127 43 -65 79 -121 79 -124 0 -3 -57 -62 -126 -132 l-125 -126 66
-64 c37 -35 71 -63 77 -61 5 1 7 -1 4 -6 -3 -5 57 -70 132 -145 l137 -137 124
125 c69 69 129 125 134 125 4 0 23 -11 41 -25 18 -14 38 -25 44 -25 6 0 12 -4
14 -8 5 -12 56 -46 153 -102 62 -36 90 -47 96 -39 5 8 8 7 10 -5 3 -10 31 -30
69 -46 49 -22 64 -33 62 -47 -2 -10 -21 -84 -43 -164 -40 -152 -46 -184 -29
-174 5 3 17 1 27 -5 10 -5 113 -35 228 -65 116 -30 227 -60 248 -67 20 -6 40
-9 43 -6 3 3 26 83 51 177 l46 171 41 -7 c78 -14 467 -9 514 6 23 8 42 18 42
23 0 4 4 7 8 5 15 -4 82 48 77 60 -2 7 1 12 8 10 7 -1 25 23 40 53 25 49 28
63 24 125 -4 80 -22 121 -76 176 -67 67 -85 70 -371 73 -212 3 -271 7 -350 24
-335 72 -622 225 -850 451 -41 41 -79 74 -85 72 -5 -1 -7 1 -2 5 9 10 -22 44
-40 44 -8 0 -11 4 -8 10 3 5 -14 37 -40 69 -133 174 -231 390 -291 646 -21 91
-26 144 -31 305 -6 216 9 342 62 525 29 101 111 301 133 328 8 9 11 17 6 17
-5 0 -4 4 1 8 6 4 26 32 45 62 19 30 54 81 78 113 24 31 40 62 37 67 -3 6 -1
10 5 10 6 0 60 48 118 108 100 100 256 222 347 271 76 41 164 86 172 88 4 2
60 21 123 43 189 65 279 81 500 87 170 5 212 2 325 -17 150 -25 330 -81 460
-145 105 -51 167 -86 177 -100 5 -7 8 -7 8 0 0 6 5 2 11 -7 5 -10 14 -18 19
-18 6 0 18 -6 27 -14 166 -136 215 -181 283 -259 115 -130 205 -269 271 -414
51 -112 86 -217 116 -353 24 -105 27 -137 29 -373 2 -243 3 -260 24 -300 28
-54 50 -78 63 -70 6 3 7 1 3 -5 -4 -6 13 -22 41 -39 42 -24 58 -28 128 -28 63
0 89 5 121 22 53 28 99 81 132 152 25 55 26 61 26 266 1 116 -2 233 -7 261 -8
55 -9 54 58 69 105 24 263 70 273 79 12 12 -6 89 -111 473 l-22 81 -35 -4
c-19 -2 -98 -22 -175 -43 -130 -36 -172 -41 -160 -21 7 11 -107 240 -115 235
-4 -2 -7 2 -7 10 0 18 -123 205 -134 205 -30 0 7 52 115 160 116 116 123 126
109 143 -9 9 -22 17 -30 17 -8 0 -12 4 -8 10 7 12 -33 53 -45 45 -5 -3 -12 0
-16 6 -4 8 -3 9 4 5 7 -4 12 -2 12 3 0 6 -7 11 -15 11 -8 0 -15 6 -15 13 0 17
-39 49 -50 42 -6 -3 -7 1 -4 9 4 11 0 16 -10 16 -9 0 -16 7 -16 15 0 8 -7 15
-15 15 -8 0 -15 5 -15 11 0 14 -25 39 -39 39 -6 0 -11 7 -11 15 0 8 -6 15 -14
15 -8 0 -17 7 -20 16 -3 8 -11 12 -16 9 -6 -4 -10 -3 -9 2 3 20 -2 34 -11 28
-5 -3 -10 0 -10 8 0 8 -10 21 -22 30 -22 15 -27 12 -151 -111 -97 -97 -130
-125 -141 -117 -115 82 -226 148 -338 203 -106 52 -137 71 -137 87 -1 11 17
85 39 165 22 80 40 152 40 160 0 12 -66 33 -275 89 -152 41 -278 71 -281 68
-5 -4 -61 -202 -63 -222 -1 -3 -8 -32 -18 -65 l-16 -60 -56 8 c-72 9 -423 9
-477 -1 l-41 -7 -33 123 c-66 253 -57 237 -125 216z"/>
<path d="M2581 3660 c-84 -11 -158 -21 -162 -22 -5 -2 2 -15 16 -30 14 -15 25
-30 25 -33 0 -8 231 -319 246 -331 8 -6 14 -15 14 -19 0 -5 46 -69 102 -144
191 -253 218 -296 218 -340 0 -44 -21 -83 -132 -248 -125 -187 -134 -193 -302
-247 -203 -64 -249 -76 -296 -76 -55 0 -86 23 -151 113 -29 39 -57 76 -61 82
-5 5 -33 44 -64 85 -30 41 -59 77 -64 78 -6 2 -10 8 -10 13 0 15 -191 269
-202 269 -6 0 -8 3 -5 6 4 4 -4 19 -16 35 -12 15 -46 61 -76 103 -41 56 -57
72 -65 63 -16 -16 -124 -265 -141 -324 -45 -155 -14 -390 68 -519 55 -87 210
-289 223 -292 9 -2 13 -9 11 -15 -5 -17 105 -162 172 -225 96 -92 296 -172
428 -172 21 0 147 17 280 38 l242 39 193 -193 c106 -106 196 -190 202 -187 5
3 6 2 3 -4 -8 -13 277 -296 288 -286 4 5 5 3 2 -3 -8 -14 96 -117 108 -107 4
5 5 3 2 -3 -8 -14 214 -233 278 -273 84 -53 170 -74 283 -69 53 3 108 10 122
15 14 6 27 10 30 10 9 -2 73 37 127 76 54 38 78 68 65 82 -4 5 -2 5 5 1 17
-10 68 74 93 153 26 83 27 207 1 290 -23 76 -68 154 -83 145 -7 -5 -8 -2 -3 6
5 8 -155 174 -496 516 -277 277 -505 508 -507 513 -2 5 14 42 34 83 59 116 75
174 81 283 6 115 -11 217 -51 309 -30 67 -225 336 -244 336 -7 0 -10 4 -7 10
8 12 -26 59 -42 60 -7 0 -10 6 -8 13 3 6 -11 29 -30 51 -19 21 -35 42 -35 46
0 10 -101 108 -136 131 -16 10 -35 17 -42 14 -7 -3 -10 0 -7 5 6 10 -56 46
-90 52 -11 1 -22 6 -25 9 -10 12 -127 38 -190 43 -36 2 -134 -4 -219 -14z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -0,0 +1,19 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,986 @@
<?php
// TO DO: better exceptions, use params
class tree
{
protected $db = null;
protected $options = null;
protected $default = array(
'structure_table' => 'structure', // the structure table (containing the id, left, right, level, parent_id and position fields)
'data_table' => 'structure', // table for additional fields (apart from structure ones, can be the same as structure_table)
'data2structure' => 'id', // which field from the data table maps to the structure table
'structure' => array( // which field (value) maps to what in the structure (key)
'id' => 'id',
'left' => 'lft',
'right' => 'rgt',
'level' => 'lvl',
'parent_id' => 'pid',
'position' => 'pos'
),
'data' => array() // array of additional fields from the data table
);
public function __construct(\vakata\database\IDB $db, array $options = array()) {
$this->db = $db;
$this->options = array_merge($this->default, $options);
}
public function get_node($id, $options = array()) {
$node = $this->db->one("
SELECT
s.".implode(", s.", $this->options['structure']).",
d.".implode(", d.", $this->options['data'])."
FROM
".$this->options['structure_table']." s,
".$this->options['data_table']." d
WHERE
s.".$this->options['structure']['id']." = d.".$this->options['data2structure']." AND
s.".$this->options['structure']['id']." = ".(int)$id
);
if(!$node) {
throw new Exception('Node does not exist');
}
if(isset($options['with_children'])) {
$node['children'] = $this->get_children($id, isset($options['deep_children']));
}
if(isset($options['with_path'])) {
$node['path'] = $this->get_path($id);
}
return $node;
}
public function get_children($id, $recursive = false) {
$sql = false;
if($recursive) {
$node = $this->get_node($id);
$sql = "
SELECT
s.".implode(", s.", $this->options['structure']).",
d.".implode(", d.", $this->options['data'])."
FROM
".$this->options['structure_table']." s,
".$this->options['data_table']." d
WHERE
s.".$this->options['structure']['id']." = d.".$this->options['data2structure']." AND
s.".$this->options['structure']['left']." > ".(int)$node[$this->options['structure']['left']]." AND
s.".$this->options['structure']['right']." < ".(int)$node[$this->options['structure']['right']]."
ORDER BY
s.".$this->options['structure']['left']."
";
}
else {
$sql = "
SELECT
s.".implode(", s.", $this->options['structure']).",
d.".implode(", d.", $this->options['data'])."
FROM
".$this->options['structure_table']." s,
".$this->options['data_table']." d
WHERE
s.".$this->options['structure']['id']." = d.".$this->options['data2structure']." AND
s.".$this->options['structure']['parent_id']." = ".(int)$id."
ORDER BY
s.".$this->options['structure']['position']."
";
}
return $this->db->all($sql);
}
public function get_path($id) {
$node = $this->get_node($id);
$sql = false;
if($node) {
$sql = "
SELECT
s.".implode(", s.", $this->options['structure']).",
d.".implode(", d.", $this->options['data'])."
FROM
".$this->options['structure_table']." s,
".$this->options['data_table']." d
WHERE
s.".$this->options['structure']['id']." = d.".$this->options['data2structure']." AND
s.".$this->options['structure']['left']." < ".(int)$node[$this->options['structure']['left']]." AND
s.".$this->options['structure']['right']." > ".(int)$node[$this->options['structure']['right']]."
ORDER BY
s.".$this->options['structure']['left']."
";
}
return $sql ? $this->db->all($sql) : false;
}
public function mk($parent, $position = 0, $data = array()) {
$parent = (int)$parent;
if($parent == 0) { throw new Exception('Parent is 0'); }
$parent = $this->get_node($parent, array('with_children'=> true));
if(!$parent['children']) { $position = 0; }
if($parent['children'] && $position >= count($parent['children'])) { $position = count($parent['children']); }
$sql = array();
$par = array();
// PREPARE NEW PARENT
// update positions of all next elements
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["position"]." = ".$this->options['structure']["position"]." + 1
WHERE
".$this->options['structure']["parent_id"]." = ".(int)$parent[$this->options['structure']['id']]." AND
".$this->options['structure']["position"]." >= ".$position."
";
$par[] = false;
// update left indexes
$ref_lft = false;
if(!$parent['children']) {
$ref_lft = $parent[$this->options['structure']["right"]];
}
else if(!isset($parent['children'][$position])) {
$ref_lft = $parent[$this->options['structure']["right"]];
}
else {
$ref_lft = $parent['children'][(int)$position][$this->options['structure']["left"]];
}
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["left"]." = ".$this->options['structure']["left"]." + 2
WHERE
".$this->options['structure']["left"]." >= ".(int)$ref_lft."
";
$par[] = false;
// update right indexes
$ref_rgt = false;
if(!$parent['children']) {
$ref_rgt = $parent[$this->options['structure']["right"]];
}
else if(!isset($parent['children'][$position])) {
$ref_rgt = $parent[$this->options['structure']["right"]];
}
else {
$ref_rgt = $parent['children'][(int)$position][$this->options['structure']["left"]] + 1;
}
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["right"]." = ".$this->options['structure']["right"]." + 2
WHERE
".$this->options['structure']["right"]." >= ".(int)$ref_rgt."
";
$par[] = false;
// INSERT NEW NODE IN STRUCTURE
$sql[] = "INSERT INTO ".$this->options['structure_table']." (".implode(",", $this->options['structure']).") VALUES (?".str_repeat(',?', count($this->options['structure']) - 1).")";
$tmp = array();
foreach($this->options['structure'] as $k => $v) {
switch($k) {
case 'id':
$tmp[] = null;
break;
case 'left':
$tmp[] = (int)$ref_lft;
break;
case 'right':
$tmp[] = (int)$ref_lft + 1;
break;
case 'level':
$tmp[] = (int)$parent[$v] + 1;
break;
case 'parent_id':
$tmp[] = $parent[$this->options['structure']['id']];
break;
case 'position':
$tmp[] = $position;
break;
default:
$tmp[] = null;
}
}
$par[] = $tmp;
foreach($sql as $k => $v) {
try {
$this->db->query($v, $par[$k]);
} catch(Exception $e) {
$this->reconstruct();
throw new Exception('Could not create');
}
}
if($data && count($data)) {
$node = $this->db->insert_id();
if(!$this->rn($node,$data)) {
$this->rm($node);
throw new Exception('Could not rename after create');
}
}
return $node;
}
public function mv($id, $parent, $position = 0) {
$id = (int)$id;
$parent = (int)$parent;
if($parent == 0 || $id == 0 || $id == 1) {
throw new Exception('Cannot move inside 0, or move root node');
}
$parent = $this->get_node($parent, array('with_children'=> true, 'with_path' => true));
$id = $this->get_node($id, array('with_children'=> true, 'deep_children' => true, 'with_path' => true));
if(!$parent['children']) {
$position = 0;
}
if($id[$this->options['structure']['parent_id']] == $parent[$this->options['structure']['id']] && $position > $id[$this->options['structure']['position']]) {
$position ++;
}
if($parent['children'] && $position >= count($parent['children'])) {
$position = count($parent['children']);
}
if($id[$this->options['structure']['left']] < $parent[$this->options['structure']['left']] && $id[$this->options['structure']['right']] > $parent[$this->options['structure']['right']]) {
throw new Exception('Could not move parent inside child');
}
$tmp = array();
$tmp[] = (int)$id[$this->options['structure']["id"]];
if($id['children'] && is_array($id['children'])) {
foreach($id['children'] as $c) {
$tmp[] = (int)$c[$this->options['structure']["id"]];
}
}
$width = (int)$id[$this->options['structure']["right"]] - (int)$id[$this->options['structure']["left"]] + 1;
$sql = array();
// PREPARE NEW PARENT
// update positions of all next elements
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["position"]." = ".$this->options['structure']["position"]." + 1
WHERE
".$this->options['structure']["id"]." != ".(int)$id[$this->options['structure']['id']]." AND
".$this->options['structure']["parent_id"]." = ".(int)$parent[$this->options['structure']['id']]." AND
".$this->options['structure']["position"]." >= ".$position."
";
// update left indexes
$ref_lft = false;
if(!$parent['children']) {
$ref_lft = $parent[$this->options['structure']["right"]];
}
else if(!isset($parent['children'][$position])) {
$ref_lft = $parent[$this->options['structure']["right"]];
}
else {
$ref_lft = $parent['children'][(int)$position][$this->options['structure']["left"]];
}
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["left"]." = ".$this->options['structure']["left"]." + ".$width."
WHERE
".$this->options['structure']["left"]." >= ".(int)$ref_lft." AND
".$this->options['structure']["id"]." NOT IN(".implode(',',$tmp).")
";
// update right indexes
$ref_rgt = false;
if(!$parent['children']) {
$ref_rgt = $parent[$this->options['structure']["right"]];
}
else if(!isset($parent['children'][$position])) {
$ref_rgt = $parent[$this->options['structure']["right"]];
}
else {
$ref_rgt = $parent['children'][(int)$position][$this->options['structure']["left"]] + 1;
}
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["right"]." = ".$this->options['structure']["right"]." + ".$width."
WHERE
".$this->options['structure']["right"]." >= ".(int)$ref_rgt." AND
".$this->options['structure']["id"]." NOT IN(".implode(',',$tmp).")
";
// MOVE THE ELEMENT AND CHILDREN
// left, right and level
$diff = $ref_lft - (int)$id[$this->options['structure']["left"]];
if($diff > 0) { $diff = $diff - $width; }
$ldiff = ((int)$parent[$this->options['structure']['level']] + 1) - (int)$id[$this->options['structure']['level']];
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["right"]." = ".$this->options['structure']["right"]." + ".$diff.",
".$this->options['structure']["left"]." = ".$this->options['structure']["left"]." + ".$diff.",
".$this->options['structure']["level"]." = ".$this->options['structure']["level"]." + ".$ldiff."
WHERE ".$this->options['structure']["id"]." IN(".implode(',',$tmp).")
";
// position and parent_id
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["position"]." = ".$position.",
".$this->options['structure']["parent_id"]." = ".(int)$parent[$this->options['structure']["id"]]."
WHERE ".$this->options['structure']["id"]." = ".(int)$id[$this->options['structure']['id']]."
";
// CLEAN OLD PARENT
// position of all next elements
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["position"]." = ".$this->options['structure']["position"]." - 1
WHERE
".$this->options['structure']["parent_id"]." = ".(int)$id[$this->options['structure']["parent_id"]]." AND
".$this->options['structure']["position"]." > ".(int)$id[$this->options['structure']["position"]];
// left indexes
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["left"]." = ".$this->options['structure']["left"]." - ".$width."
WHERE
".$this->options['structure']["left"]." > ".(int)$id[$this->options['structure']["right"]]." AND
".$this->options['structure']["id"]." NOT IN(".implode(',',$tmp).")
";
// right indexes
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["right"]." = ".$this->options['structure']["right"]." - ".$width."
WHERE
".$this->options['structure']["right"]." > ".(int)$id[$this->options['structure']["right"]]." AND
".$this->options['structure']["id"]." NOT IN(".implode(',',$tmp).")
";
foreach($sql as $k => $v) {
//echo preg_replace('@[\s\t]+@',' ',$v) ."\n";
try {
$this->db->query($v);
} catch(Exception $e) {
$this->reconstruct();
throw new Exception('Error moving');
}
}
return true;
}
public function cp($id, $parent, $position = 0) {
$id = (int)$id;
$parent = (int)$parent;
if($parent == 0 || $id == 0 || $id == 1) {
throw new Exception('Could not copy inside parent 0, or copy root nodes');
}
$parent = $this->get_node($parent, array('with_children'=> true, 'with_path' => true));
$id = $this->get_node($id, array('with_children'=> true, 'deep_children' => true, 'with_path' => true));
$old_nodes = $this->db->get("
SELECT * FROM ".$this->options['structure_table']."
WHERE ".$this->options['structure']["left"]." > ".$id[$this->options['structure']["left"]]." AND ".$this->options['structure']["right"]." < ".$id[$this->options['structure']["right"]]."
ORDER BY ".$this->options['structure']["left"]."
");
if(!$parent['children']) {
$position = 0;
}
if($id[$this->options['structure']['parent_id']] == $parent[$this->options['structure']['id']] && $position > $id[$this->options['structure']['position']]) {
//$position ++;
}
if($parent['children'] && $position >= count($parent['children'])) {
$position = count($parent['children']);
}
$tmp = array();
$tmp[] = (int)$id[$this->options['structure']["id"]];
if($id['children'] && is_array($id['children'])) {
foreach($id['children'] as $c) {
$tmp[] = (int)$c[$this->options['structure']["id"]];
}
}
$width = (int)$id[$this->options['structure']["right"]] - (int)$id[$this->options['structure']["left"]] + 1;
$sql = array();
// PREPARE NEW PARENT
// update positions of all next elements
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["position"]." = ".$this->options['structure']["position"]." + 1
WHERE
".$this->options['structure']["parent_id"]." = ".(int)$parent[$this->options['structure']['id']]." AND
".$this->options['structure']["position"]." >= ".$position."
";
// update left indexes
$ref_lft = false;
if(!$parent['children']) {
$ref_lft = $parent[$this->options['structure']["right"]];
}
else if(!isset($parent['children'][$position])) {
$ref_lft = $parent[$this->options['structure']["right"]];
}
else {
$ref_lft = $parent['children'][(int)$position][$this->options['structure']["left"]];
}
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["left"]." = ".$this->options['structure']["left"]." + ".$width."
WHERE
".$this->options['structure']["left"]." >= ".(int)$ref_lft."
";
// update right indexes
$ref_rgt = false;
if(!$parent['children']) {
$ref_rgt = $parent[$this->options['structure']["right"]];
}
else if(!isset($parent['children'][$position])) {
$ref_rgt = $parent[$this->options['structure']["right"]];
}
else {
$ref_rgt = $parent['children'][(int)$position][$this->options['structure']["left"]] + 1;
}
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["right"]." = ".$this->options['structure']["right"]." + ".$width."
WHERE
".$this->options['structure']["right"]." >= ".(int)$ref_rgt."
";
// MOVE THE ELEMENT AND CHILDREN
// left, right and level
$diff = $ref_lft - (int)$id[$this->options['structure']["left"]];
if($diff <= 0) { $diff = $diff - $width; }
$ldiff = ((int)$parent[$this->options['structure']['level']] + 1) - (int)$id[$this->options['structure']['level']];
// build all fields + data table
$fields = array_combine($this->options['structure'], $this->options['structure']);
unset($fields['id']);
$fields[$this->options['structure']["left"]] = $this->options['structure']["left"]." + ".$diff;
$fields[$this->options['structure']["right"]] = $this->options['structure']["right"]." + ".$diff;
$fields[$this->options['structure']["level"]] = $this->options['structure']["level"]." + ".$ldiff;
$sql[] = "
INSERT INTO ".$this->options['structure_table']." ( ".implode(',',array_keys($fields))." )
SELECT ".implode(',',array_values($fields))." FROM ".$this->options['structure_table']." WHERE ".$this->options['structure']["id"]." IN (".implode(",", $tmp).")
ORDER BY ".$this->options['structure']["level"]." ASC";
foreach($sql as $k => $v) {
try {
$this->db->query($v);
} catch(Exception $e) {
$this->reconstruct();
throw new Exception('Error copying');
}
}
$iid = (int)$this->db->insert_id();
try {
$this->db->query("
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["position"]." = ".$position.",
".$this->options['structure']["parent_id"]." = ".(int)$parent[$this->options['structure']["id"]]."
WHERE ".$this->options['structure']["id"]." = ".$iid."
");
} catch(Exception $e) {
$this->rm($iid);
$this->reconstruct();
throw new Exception('Could not update adjacency after copy');
}
$fields = $this->options['data'];
unset($fields['id']);
$update_fields = array();
foreach($fields as $f) {
$update_fields[] = $f.'=VALUES('.$f.')';
}
$update_fields = implode(',', $update_fields);
if(count($fields)) {
try {
$this->db->query("
INSERT INTO ".$this->options['data_table']." (".$this->options['data2structure'].",".implode(",",$fields).")
SELECT ".$iid.",".implode(",",$fields)." FROM ".$this->options['data_table']." WHERE ".$this->options['data2structure']." = ".$id[$this->options['data2structure']]."
ON DUPLICATE KEY UPDATE ".$update_fields."
");
}
catch(Exception $e) {
$this->rm($iid);
$this->reconstruct();
throw new Exception('Could not update data after copy');
}
}
// manually fix all parent_ids and copy all data
$new_nodes = $this->db->get("
SELECT * FROM ".$this->options['structure_table']."
WHERE ".$this->options['structure']["left"]." > ".$ref_lft." AND ".$this->options['structure']["right"]." < ".($ref_lft + $width - 1)." AND ".$this->options['structure']["id"]." != ".$iid."
ORDER BY ".$this->options['structure']["left"]."
");
$parents = array();
foreach($new_nodes as $node) {
if(!isset($parents[$node[$this->options['structure']["left"]]])) { $parents[$node[$this->options['structure']["left"]]] = $iid; }
for($i = $node[$this->options['structure']["left"]] + 1; $i < $node[$this->options['structure']["right"]]; $i++) {
$parents[$i] = $node[$this->options['structure']["id"]];
}
}
$sql = array();
foreach($new_nodes as $k => $node) {
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["parent_id"]." = ".$parents[$node[$this->options['structure']["left"]]]."
WHERE ".$this->options['structure']["id"]." = ".(int)$node[$this->options['structure']["id"]]."
";
if(count($fields)) {
$up = "";
foreach($fields as $f)
$sql[] = "
INSERT INTO ".$this->options['data_table']." (".$this->options['data2structure'].",".implode(",",$fields).")
SELECT ".(int)$node[$this->options['structure']["id"]].",".implode(",",$fields)." FROM ".$this->options['data_table']."
WHERE ".$this->options['data2structure']." = ".$old_nodes[$k][$this->options['structure']['id']]."
ON DUPLICATE KEY UPDATE ".$update_fields."
";
}
}
//var_dump($sql);
foreach($sql as $k => $v) {
try {
$this->db->query($v);
} catch(Exception $e) {
$this->rm($iid);
$this->reconstruct();
throw new Exception('Error copying');
}
}
return $iid;
}
public function rm($id) {
$id = (int)$id;
if(!$id || $id === 1) { throw new Exception('Could not create inside roots'); }
$data = $this->get_node($id, array('with_children' => true, 'deep_children' => true));
$lft = (int)$data[$this->options['structure']["left"]];
$rgt = (int)$data[$this->options['structure']["right"]];
$pid = (int)$data[$this->options['structure']["parent_id"]];
$pos = (int)$data[$this->options['structure']["position"]];
$dif = $rgt - $lft + 1;
$sql = array();
// deleting node and its children from structure
$sql[] = "
DELETE FROM ".$this->options['structure_table']."
WHERE ".$this->options['structure']["left"]." >= ".(int)$lft." AND ".$this->options['structure']["right"]." <= ".(int)$rgt."
";
// shift left indexes of nodes right of the node
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["left"]." = ".$this->options['structure']["left"]." - ".(int)$dif."
WHERE ".$this->options['structure']["left"]." > ".(int)$rgt."
";
// shift right indexes of nodes right of the node and the node's parents
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["right"]." = ".$this->options['structure']["right"]." - ".(int)$dif."
WHERE ".$this->options['structure']["right"]." > ".(int)$lft."
";
// Update position of siblings below the deleted node
$sql[] = "
UPDATE ".$this->options['structure_table']."
SET ".$this->options['structure']["position"]." = ".$this->options['structure']["position"]." - 1
WHERE ".$this->options['structure']["parent_id"]." = ".$pid." AND ".$this->options['structure']["position"]." > ".(int)$pos."
";
// delete from data table
if($this->options['data_table']) {
$tmp = array();
$tmp[] = (int)$data['id'];
if($data['children'] && is_array($data['children'])) {
foreach($data['children'] as $v) {
$tmp[] = (int)$v['id'];
}
}
$sql[] = "DELETE FROM ".$this->options['data_table']." WHERE ".$this->options['data2structure']." IN (".implode(',',$tmp).")";
}
foreach($sql as $v) {
try {
$this->db->query($v);
} catch(Exception $e) {
$this->reconstruct();
throw new Exception('Could not remove');
}
}
return true;
}
public function rn($id, $data) {
if(!(int)$this->db->one('SELECT 1 AS res FROM '.$this->options['structure_table'].' WHERE '.$this->options['structure']['id'].' = '.(int)$id)) {
throw new Exception('Could not rename non-existing node');
}
$tmp = array();
foreach($this->options['data'] as $v) {
if(isset($data[$v])) {
$tmp[$v] = $data[$v];
}
}
if(count($tmp)) {
$tmp[$this->options['data2structure']] = $id;
$sql = "
INSERT INTO
".$this->options['data_table']." (".implode(',', array_keys($tmp)).")
VALUES(?".str_repeat(',?', count($tmp) - 1).")
ON DUPLICATE KEY UPDATE
".implode(' = ?, ', array_keys($tmp))." = ?";
$par = array_merge(array_values($tmp), array_values($tmp));
try {
$this->db->query($sql, $par);
}
catch(Exception $e) {
throw new Exception('Could not rename');
}
}
return true;
}
public function analyze($get_errors = false) {
$report = array();
if((int)$this->db->one("SELECT COUNT(".$this->options['structure']["id"].") AS res FROM ".$this->options['structure_table']." WHERE ".$this->options['structure']["parent_id"]." = 0") !== 1) {
$report[] = "No or more than one root node.";
}
if((int)$this->db->one("SELECT ".$this->options['structure']["left"]." AS res FROM ".$this->options['structure_table']." WHERE ".$this->options['structure']["parent_id"]." = 0") !== 1) {
$report[] = "Root node's left index is not 1.";
}
if((int)$this->db->one("
SELECT
COUNT(".$this->options['structure']['id'].") AS res
FROM ".$this->options['structure_table']." s
WHERE
".$this->options['structure']["parent_id"]." != 0 AND
(SELECT COUNT(".$this->options['structure']['id'].") FROM ".$this->options['structure_table']." WHERE ".$this->options['structure']["id"]." = s.".$this->options['structure']["parent_id"].") = 0") > 0
) {
$report[] = "Missing parents.";
}
if(
(int)$this->db->one("SELECT MAX(".$this->options['structure']["right"].") AS res FROM ".$this->options['structure_table']) / 2 !=
(int)$this->db->one("SELECT COUNT(".$this->options['structure']["id"].") AS res FROM ".$this->options['structure_table'])
) {
$report[] = "Right index does not match node count.";
}
if(
(int)$this->db->one("SELECT COUNT(DISTINCT ".$this->options['structure']["right"].") AS res FROM ".$this->options['structure_table']) !=
(int)$this->db->one("SELECT COUNT(DISTINCT ".$this->options['structure']["left"].") AS res FROM ".$this->options['structure_table'])
) {
$report[] = "Duplicates in nested set.";
}
if(
(int)$this->db->one("SELECT COUNT(DISTINCT ".$this->options['structure']["id"].") AS res FROM ".$this->options['structure_table']) !=
(int)$this->db->one("SELECT COUNT(DISTINCT ".$this->options['structure']["left"].") AS res FROM ".$this->options['structure_table'])
) {
$report[] = "Left indexes not unique.";
}
if(
(int)$this->db->one("SELECT COUNT(DISTINCT ".$this->options['structure']["id"].") AS res FROM ".$this->options['structure_table']) !=
(int)$this->db->one("SELECT COUNT(DISTINCT ".$this->options['structure']["right"].") AS res FROM ".$this->options['structure_table'])
) {
$report[] = "Right indexes not unique.";
}
if(
(int)$this->db->one("
SELECT
s1.".$this->options['structure']["id"]." AS res
FROM ".$this->options['structure_table']." s1, ".$this->options['structure_table']." s2
WHERE
s1.".$this->options['structure']['id']." != s2.".$this->options['structure']['id']." AND
s1.".$this->options['structure']['left']." = s2.".$this->options['structure']['right']."
LIMIT 1")
) {
$report[] = "Nested set - matching left and right indexes.";
}
if(
(int)$this->db->one("
SELECT
".$this->options['structure']["id"]." AS res
FROM ".$this->options['structure_table']." s
WHERE
".$this->options['structure']['position']." >= (
SELECT
COUNT(".$this->options['structure']["id"].")
FROM ".$this->options['structure_table']."
WHERE ".$this->options['structure']['parent_id']." = s.".$this->options['structure']['parent_id']."
)
LIMIT 1") ||
(int)$this->db->one("
SELECT
s1.".$this->options['structure']["id"]." AS res
FROM ".$this->options['structure_table']." s1, ".$this->options['structure_table']." s2
WHERE
s1.".$this->options['structure']['id']." != s2.".$this->options['structure']['id']." AND
s1.".$this->options['structure']['parent_id']." = s2.".$this->options['structure']['parent_id']." AND
s1.".$this->options['structure']['position']." = s2.".$this->options['structure']['position']."
LIMIT 1")
) {
$report[] = "Positions not correct.";
}
if((int)$this->db->one("
SELECT
COUNT(".$this->options['structure']["id"].") FROM ".$this->options['structure_table']." s
WHERE
(
SELECT
COUNT(".$this->options['structure']["id"].")
FROM ".$this->options['structure_table']."
WHERE
".$this->options['structure']["right"]." < s.".$this->options['structure']["right"]." AND
".$this->options['structure']["left"]." > s.".$this->options['structure']["left"]." AND
".$this->options['structure']["level"]." = s.".$this->options['structure']["level"]." + 1
) !=
(
SELECT
COUNT(*)
FROM ".$this->options['structure_table']."
WHERE
".$this->options['structure']["parent_id"]." = s.".$this->options['structure']["id"]."
)")
) {
$report[] = "Adjacency and nested set do not match.";
}
if(
$this->options['data_table'] &&
(int)$this->db->one("
SELECT
COUNT(".$this->options['structure']["id"].") AS res
FROM ".$this->options['structure_table']." s
WHERE
(SELECT COUNT(".$this->options['data2structure'].") FROM ".$this->options['data_table']." WHERE ".$this->options['data2structure']." = s.".$this->options['structure']["id"].") = 0
")
) {
$report[] = "Missing records in data table.";
}
if(
$this->options['data_table'] &&
(int)$this->db->one("
SELECT
COUNT(".$this->options['data2structure'].") AS res
FROM ".$this->options['data_table']." s
WHERE
(SELECT COUNT(".$this->options['structure']["id"].") FROM ".$this->options['structure_table']." WHERE ".$this->options['structure']["id"]." = s.".$this->options['data2structure'].") = 0
")
) {
$report[] = "Dangling records in data table.";
}
return $get_errors ? $report : count($report) == 0;
}
public function reconstruct($analyze = true) {
if($analyze && $this->analyze()) { return true; }
if(!$this->db->query("" .
"CREATE TEMPORARY TABLE temp_tree (" .
"".$this->options['structure']["id"]." INTEGER NOT NULL, " .
"".$this->options['structure']["parent_id"]." INTEGER NOT NULL, " .
"". $this->options['structure']["position"]." INTEGER NOT NULL" .
") "
)) { return false; }
if(!$this->db->query("" .
"INSERT INTO temp_tree " .
"SELECT " .
"".$this->options['structure']["id"].", " .
"".$this->options['structure']["parent_id"].", " .
"".$this->options['structure']["position"]." " .
"FROM ".$this->options['structure_table'].""
)) { return false; }
if(!$this->db->query("" .
"CREATE TEMPORARY TABLE temp_stack (" .
"".$this->options['structure']["id"]." INTEGER NOT NULL, " .
"".$this->options['structure']["left"]." INTEGER, " .
"".$this->options['structure']["right"]." INTEGER, " .
"".$this->options['structure']["level"]." INTEGER, " .
"stack_top INTEGER NOT NULL, " .
"".$this->options['structure']["parent_id"]." INTEGER, " .
"".$this->options['structure']["position"]." INTEGER " .
") "
)) { return false; }
$counter = 2;
if(!$this->db->query("SELECT COUNT(*) FROM temp_tree")) {
return false;
}
$this->db->nextr();
$maxcounter = (int) $this->db->f(0) * 2;
$currenttop = 1;
if(!$this->db->query("" .
"INSERT INTO temp_stack " .
"SELECT " .
"".$this->options['structure']["id"].", " .
"1, " .
"NULL, " .
"0, " .
"1, " .
"".$this->options['structure']["parent_id"].", " .
"".$this->options['structure']["position"]." " .
"FROM temp_tree " .
"WHERE ".$this->options['structure']["parent_id"]." = 0"
)) { return false; }
if(!$this->db->query("DELETE FROM temp_tree WHERE ".$this->options['structure']["parent_id"]." = 0")) {
return false;
}
while ($counter <= $maxcounter) {
if(!$this->db->query("" .
"SELECT " .
"temp_tree.".$this->options['structure']["id"]." AS tempmin, " .
"temp_tree.".$this->options['structure']["parent_id"]." AS pid, " .
"temp_tree.".$this->options['structure']["position"]." AS lid " .
"FROM temp_stack, temp_tree " .
"WHERE " .
"temp_stack.".$this->options['structure']["id"]." = temp_tree.".$this->options['structure']["parent_id"]." AND " .
"temp_stack.stack_top = ".$currenttop." " .
"ORDER BY temp_tree.".$this->options['structure']["position"]." ASC LIMIT 1"
)) { return false; }
if($this->db->nextr()) {
$tmp = $this->db->f("tempmin");
$q = "INSERT INTO temp_stack (stack_top, ".$this->options['structure']["id"].", ".$this->options['structure']["left"].", ".$this->options['structure']["right"].", ".$this->options['structure']["level"].", ".$this->options['structure']["parent_id"].", ".$this->options['structure']["position"].") VALUES(".($currenttop + 1).", ".$tmp.", ".$counter.", NULL, ".$currenttop.", ".$this->db->f("pid").", ".$this->db->f("lid").")";
if(!$this->db->query($q)) {
return false;
}
if(!$this->db->query("DELETE FROM temp_tree WHERE ".$this->options['structure']["id"]." = ".$tmp)) {
return false;
}
$counter++;
$currenttop++;
}
else {
if(!$this->db->query("" .
"UPDATE temp_stack SET " .
"".$this->options['structure']["right"]." = ".$counter.", " .
"stack_top = -stack_top " .
"WHERE stack_top = ".$currenttop
)) { return false; }
$counter++;
$currenttop--;
}
}
$temp_fields = $this->options['structure'];
unset($temp_fields["parent_id"]);
unset($temp_fields["position"]);
unset($temp_fields["left"]);
unset($temp_fields["right"]);
unset($temp_fields["level"]);
if(count($temp_fields) > 1) {
if(!$this->db->query("" .
"CREATE TEMPORARY TABLE temp_tree2 " .
"SELECT ".implode(", ", $temp_fields)." FROM ".$this->options['structure_table']." "
)) { return false; }
}
if(!$this->db->query("TRUNCATE TABLE ".$this->options['structure_table']."")) {
return false;
}
if(!$this->db->query("" .
"INSERT INTO ".$this->options['structure_table']." (" .
"".$this->options['structure']["id"].", " .
"".$this->options['structure']["parent_id"].", " .
"".$this->options['structure']["position"].", " .
"".$this->options['structure']["left"].", " .
"".$this->options['structure']["right"].", " .
"".$this->options['structure']["level"]." " .
") " .
"SELECT " .
"".$this->options['structure']["id"].", " .
"".$this->options['structure']["parent_id"].", " .
"".$this->options['structure']["position"].", " .
"".$this->options['structure']["left"].", " .
"".$this->options['structure']["right"].", " .
"".$this->options['structure']["level"]." " .
"FROM temp_stack " .
"ORDER BY ".$this->options['structure']["id"].""
)) {
return false;
}
if(count($temp_fields) > 1) {
$sql = "" .
"UPDATE ".$this->options['structure_table']." v, temp_tree2 SET v.".$this->options['structure']["id"]." = v.".$this->options['structure']["id"]." ";
foreach($temp_fields as $k => $v) {
if($k == "id") continue;
$sql .= ", v.".$v." = temp_tree2.".$v." ";
}
$sql .= " WHERE v.".$this->options['structure']["id"]." = temp_tree2.".$this->options['structure']["id"]." ";
if(!$this->db->query($sql)) {
return false;
}
}
// fix positions
$nodes = $this->db->get("SELECT ".$this->options['structure']['id'].", ".$this->options['structure']['parent_id']." FROM ".$this->options['structure_table']." ORDER BY ".$this->options['structure']['parent_id'].", ".$this->options['structure']['position']);
$last_parent = false;
$last_position = false;
foreach($nodes as $node) {
if((int)$node[$this->options['structure']['parent_id']] !== $last_parent) {
$last_position = 0;
$last_parent = (int)$node[$this->options['structure']['parent_id']];
}
$this->db->query("UPDATE ".$this->options['structure_table']." SET ".$this->options['structure']['position']." = ".$last_position." WHERE ".$this->options['structure']['id']." = ".(int)$node[$this->options['structure']['id']]);
$last_position++;
}
if($this->options['data_table'] != $this->options['structure_table']) {
// fix missing data records
$this->db->query("
INSERT INTO
".$this->options['data_table']." (".implode(',',$this->options['data']).")
SELECT ".$this->options['structure']['id']." ".str_repeat(", ".$this->options['structure']['id'], count($this->options['data']) - 1)."
FROM ".$this->options['structure_table']." s
WHERE (SELECT COUNT(".$this->options['data2structure'].") FROM ".$this->options['data_table']." WHERE ".$this->options['data2structure']." = s.".$this->options['structure']['id'].") = 0 "
);
// remove dangling data records
$this->db->query("
DELETE FROM
".$this->options['data_table']."
WHERE
(SELECT COUNT(".$this->options['structure']['id'].") FROM ".$this->options['structure_table']." WHERE ".$this->options['structure']['id']." = ".$this->options['data_table'].".".$this->options['data2structure'].") = 0
");
}
return true;
}
public function res($data = array()) {
if(!$this->db->query("TRUNCATE TABLE ".$this->options['structure_table'])) { return false; }
if(!$this->db->query("TRUNCATE TABLE ".$this->options['data_table'])) { return false; }
$sql = "INSERT INTO ".$this->options['structure_table']." (".implode(",", $this->options['structure']).") VALUES (?".str_repeat(',?', count($this->options['structure']) - 1).")";
$par = array();
foreach($this->options['structure'] as $k => $v) {
switch($k) {
case 'id':
$par[] = null;
break;
case 'left':
$par[] = 1;
break;
case 'right':
$par[] = 2;
break;
case 'level':
$par[] = 0;
break;
case 'parent_id':
$par[] = 0;
break;
case 'position':
$par[] = 0;
break;
default:
$par[] = null;
}
}
if(!$this->db->query($sql, $par)) { return false; }
$id = $this->db->insert_id();
foreach($this->options['structure'] as $k => $v) {
if(!isset($data[$k])) { $data[$k] = null; }
}
return $this->rn($id, $data);
}
public function dump() {
$nodes = $this->db->get("
SELECT
s.".implode(", s.", $this->options['structure']).",
d.".implode(", d.", $this->options['data'])."
FROM
".$this->options['structure_table']." s,
".$this->options['data_table']." d
WHERE
s.".$this->options['structure']['id']." = d.".$this->options['data2structure']."
ORDER BY ".$this->options['structure']["left"]
);
echo "\n\n";
foreach($nodes as $node) {
echo str_repeat(" ",(int)$node[$this->options['structure']["level"]] * 2);
echo $node[$this->options['structure']["id"]]." ".$node["nm"]." (".$node[$this->options['structure']["left"]].",".$node[$this->options['structure']["right"]].",".$node[$this->options['structure']["level"]].",".$node[$this->options['structure']["parent_id"]].",".$node[$this->options['structure']["position"]].")" . "\n";
}
echo str_repeat("-",40);
echo "\n\n";
}
}

View File

@@ -0,0 +1,91 @@
-- phpMyAdmin SQL Dump
-- version 4.0.1
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Generation Time: Apr 15, 2014 at 05:14 PM
-- Server version: 5.5.27
-- PHP Version: 5.4.7
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Database: `test`
--
-- --------------------------------------------------------
--
-- Table structure for table `tree_data`
--
CREATE TABLE IF NOT EXISTS `tree_data` (
`id` int(10) unsigned NOT NULL,
`nm` varchar(255) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `tree_data`
--
INSERT INTO `tree_data` (`id`, `nm`) VALUES
(1, 'root'),
(1063, 'Node 12'),
(1064, 'Node 2'),
(1065, 'Node 3'),
(1066, 'Node 4'),
(1067, 'Node 5'),
(1068, 'Node 6'),
(1069, 'Node 7'),
(1070, 'Node 8'),
(1071, 'Node 9'),
(1072, 'Node 9'),
(1073, 'Node 9'),
(1074, 'Node 9'),
(1075, 'Node 7'),
(1076, 'Node 8'),
(1077, 'Node 9'),
(1078, 'Node 9'),
(1079, 'Node 9');
-- --------------------------------------------------------
--
-- Table structure for table `tree_struct`
--
CREATE TABLE IF NOT EXISTS `tree_struct` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lft` int(10) unsigned NOT NULL,
`rgt` int(10) unsigned NOT NULL,
`lvl` int(10) unsigned NOT NULL,
`pid` int(10) unsigned NOT NULL,
`pos` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1083 ;
--
-- Dumping data for table `tree_struct`
--
INSERT INTO `tree_struct` (`id`, `lft`, `rgt`, `lvl`, `pid`, `pos`) VALUES
(1, 1, 36, 0, 0, 0),
(1063, 2, 31, 1, 1, 0),
(1064, 3, 30, 2, 1063, 0),
(1065, 4, 29, 3, 1064, 0),
(1066, 5, 28, 4, 1065, 0),
(1067, 6, 19, 5, 1066, 0),
(1068, 7, 18, 6, 1067, 0),
(1069, 8, 17, 7, 1068, 0),
(1070, 9, 16, 8, 1069, 0),
(1071, 12, 13, 9, 1070, 1),
(1072, 14, 15, 9, 1070, 2),
(1073, 10, 11, 9, 1070, 0),
(1074, 32, 35, 1, 1, 1),
(1075, 20, 27, 5, 1066, 1),
(1076, 21, 26, 6, 1075, 0),
(1077, 24, 25, 7, 1076, 1),
(1078, 33, 34, 2, 1074, 0),
(1079, 22, 23, 7, 1076, 0);

View File

@@ -0,0 +1,172 @@
<?php
require_once(dirname(__FILE__) . '/class.db.php');
require_once(dirname(__FILE__) . '/class.tree.php');
if(isset($_GET['operation'])) {
$fs = new tree(db::get('mysqli://root@127.0.0.1/test'), array('structure_table' => 'tree_struct', 'data_table' => 'tree_data', 'data' => array('nm')));
try {
$rslt = null;
switch($_GET['operation']) {
case 'analyze':
var_dump($fs->analyze(true));
die();
break;
case 'get_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;
$temp = $fs->get_children($node);
$rslt = array();
foreach($temp as $v) {
$rslt[] = array('id' => $v['id'], 'text' => $v['nm'], 'children' => ($v['rgt'] - $v['lft'] > 1));
}
break;
case "get_content":
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? $_GET['id'] : 0;
$node = explode(':', $node);
if(count($node) > 1) {
$rslt = array('content' => 'Multiple selected');
}
else {
$temp = $fs->get_node((int)$node[0], array('with_path' => true));
$rslt = array('content' => 'Selected: /' . implode('/',array_map(function ($v) { return $v['nm']; }, $temp['path'])). '/'.$temp['nm']);
}
break;
case 'create_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;
$temp = $fs->mk($node, isset($_GET['position']) ? (int)$_GET['position'] : 0, array('nm' => isset($_GET['text']) ? $_GET['text'] : 'New node'));
$rslt = array('id' => $temp);
break;
case 'rename_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;
$rslt = $fs->rn($node, array('nm' => isset($_GET['text']) ? $_GET['text'] : 'Renamed node'));
break;
case 'delete_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;
$rslt = $fs->rm($node);
break;
case 'move_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;
$parn = isset($_GET['parent']) && $_GET['parent'] !== '#' ? (int)$_GET['parent'] : 0;
$rslt = $fs->mv($node, $parn, isset($_GET['position']) ? (int)$_GET['position'] : 0);
break;
case 'copy_node':
$node = isset($_GET['id']) && $_GET['id'] !== '#' ? (int)$_GET['id'] : 0;
$parn = isset($_GET['parent']) && $_GET['parent'] !== '#' ? (int)$_GET['parent'] : 0;
$rslt = $fs->cp($node, $parn, isset($_GET['position']) ? (int)$_GET['position'] : 0);
break;
default:
throw new Exception('Unsupported operation: ' . $_GET['operation']);
break;
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode($rslt);
}
catch (Exception $e) {
header($_SERVER["SERVER_PROTOCOL"] . ' 500 Server Error');
header('Status: 500 Server Error');
echo $e->getMessage();
}
die();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Title</title>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="./../../dist/themes/default/style.min.css" />
<style>
html, body { background:#ebebeb; font-size:10px; font-family:Verdana; margin:0; padding:0; }
#container { min-width:320px; margin:0px auto 0 auto; background:white; border-radius:0px; padding:0px; overflow:hidden; }
#tree { float:left; min-width:319px; border-right:1px solid silver; overflow:auto; padding:0px 0; }
#data { margin-left:320px; }
#data textarea { margin:0; padding:0; height:100%; width:100%; border:0; background:white; display:block; line-height:18px; }
#data, #code { font: normal normal normal 12px/18px 'Consolas', monospace !important; }
</style>
</head>
<body>
<div id="container" role="main">
<div id="tree"></div>
<div id="data">
<div class="content code" style="display:none;"><textarea id="code" readonly="readonly"></textarea></div>
<div class="content folder" style="display:none;"></div>
<div class="content image" style="display:none; position:relative;"><img src="" alt="" style="display:block; position:absolute; left:50%; top:50%; padding:0; max-height:90%; max-width:90%;" /></div>
<div class="content default" style="text-align:center;">Select a node from the tree.</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="./../../dist/jstree.min.js"></script>
<script>
$(function () {
$(window).resize(function () {
var h = Math.max($(window).height() - 0, 420);
$('#container, #data, #tree, #data .content').height(h).filter('.default').css('lineHeight', h + 'px');
}).resize();
$('#tree')
.jstree({
'core' : {
'data' : {
'url' : '?operation=get_node',
'data' : function (node) {
return { 'id' : node.id };
}
},
'check_callback' : true,
'themes' : {
'responsive' : false
}
},
'force_text' : true,
'plugins' : ['state','dnd','contextmenu','wholerow']
})
.on('delete_node.jstree', function (e, data) {
$.get('?operation=delete_node', { 'id' : data.node.id })
.fail(function () {
data.instance.refresh();
});
})
.on('create_node.jstree', function (e, data) {
$.get('?operation=create_node', { 'id' : data.node.parent, 'position' : data.position, 'text' : data.node.text })
.done(function (d) {
data.instance.set_id(data.node, d.id);
})
.fail(function () {
data.instance.refresh();
});
})
.on('rename_node.jstree', function (e, data) {
$.get('?operation=rename_node', { 'id' : data.node.id, 'text' : data.text })
.fail(function () {
data.instance.refresh();
});
})
.on('move_node.jstree', function (e, data) {
$.get('?operation=move_node', { 'id' : data.node.id, 'parent' : data.parent, 'position' : data.position })
.fail(function () {
data.instance.refresh();
});
})
.on('copy_node.jstree', function (e, data) {
$.get('?operation=copy_node', { 'id' : data.original.id, 'parent' : data.parent, 'position' : data.position })
.always(function () {
data.instance.refresh();
});
})
.on('changed.jstree', function (e, data) {
if(data && data.selected && data.selected.length) {
$.get('?operation=get_content&id=' + data.selected.join(':'), function (d) {
$('#data .default').text(d.content).show();
});
}
else {
$('#data .content').hide();
$('#data .default').text('Select a file from the tree.').show();
}
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,10 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
header('Content-Type: application/json; charset=utf-8');
if( $_GET['id'] == '#')
echo '[{"id":1,"text":"RootDN","children":[{"id":2,"text":"Serveurs","children":true},{"id":3,"text":"Child node 2"}]}]';

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,4 @@
<?php
require_once 'ldapClass.php';
require_once 'userClass.php';

View File

@@ -0,0 +1,492 @@
<?php
//namespace ldapClass;
class ldapClass
{
/**
* The active LDAP connection.
*
* @var resource
*/
protected $connection;
/**
* Stores the bool whether or not
* the current connection is bound.
*
* @var bool
*/
protected $bound = false;
/**
* Stores the bool to tell the connection
* whether or not to use SSL.
*
* To use SSL, your server must support LDAP over SSL.
* http://adldap.sourceforge.net/wiki/doku.php?id=ldap_over_ssl
*
* @var bool
*/
protected $useSSL = false;
/**
* Stores the bool to tell the connection
* whether or not to use TLS.
*
* If you wish to use TLS you should ensure that $useSSL is set to false and vice-versa
*
* @var bool
*/
protected $useTLS = false;
/**
* {@inheritdoc}
*/
public function isUsingSSL()
{
return $this->useSSL;
}
/**
* {@inheritdoc}
*/
public function isUsingTLS()
{
return $this->useTLS;
}
/**
* {@inheritdoc}
*/
public function isBound()
{
return $this->bound;
}
/**
* {@inheritdoc}
*/
public function canChangePasswords()
{
return $this->isUsingSSL() || $this->isUsingTLS();
}
/**
* {@inheritdoc}
*/
public function ssl($enabled = true)
{
$this->useSSL = $enabled;
return $this;
}
/**
* {@inheritdoc}
*/
public function tls($enabled = true)
{
$this->useTLS = $enabled;
return $this;
}
/**
* {@inheritdoc}
*/
public function getConnection()
{
return $this->connection;
}
/**
* {@inheritdoc}
*/
public function getEntries($searchResults)
{
return ldap_get_entries($this->getConnection(), $searchResults);
}
/**
* {@inheritdoc}
*/
public function getFirstEntry($searchResults)
{
return ldap_first_entry($this->getConnection(), $searchResults);
}
/**
* {@inheritdoc}
*/
public function getNextEntry($entry)
{
return ldap_next_entry($this->getConnection(), $entry);
}
/**
* {@inheritdoc}
*/
public function getAttributes($entry)
{
return ldap_get_attributes($this->getConnection(), $entry);
}
/**
* {@inheritdoc}
*/
public function countEntries($searchResults)
{
return ldap_count_entries($this->getConnection(), $searchResults);
}
/**
* {@inheritdoc}
*/
public function compare($dn, $attribute, $value)
{
return ldap_compare($this->getConnection(), $dn, $attribute, $value);
}
/**
* {@inheritdoc}
*/
public function getLastError()
{
return ldap_error($this->getConnection());
}
/**
* {@inheritdoc}
*/
public function getValuesLen($entry, $attribute)
{
return ldap_get_values_len($this->getConnection(), $entry, $attribute);
}
/**
* {@inheritdoc}
*/
public function setOption($option, $value)
{
return ldap_set_option($this->getConnection(), $option, $value);
}
/**
* {@inheritdoc}
*/
public function setOptions(array $options = [])
{
foreach ($options as $option => $value) {
$this->setOption($option, $value);
}
}
/**
* {@inheritdoc}
*/
public function setRebindCallback(callable $callback)
{
return ldap_set_rebind_proc($this->getConnection(), $callback);
}
/**
* {@inheritdoc}
*/
public function startTLS()
{
return ldap_start_tls($this->getConnection());
}
/**
* {@inheritdoc}
*/
public function connect($hosts = [], $port = '389')
{
$connections = $this->getConnectionString($hosts, $this->getProtocol(), $port);
return $this->connection = ldap_connect($connections);
}
/**
* {@inheritdoc}
*/
public function close()
{
$connection = $this->getConnection();
return is_resource($connection) ? ldap_close($connection) : false;
}
/**
* {@inheritdoc}
*/
public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0)
{
return ldap_search($this->getConnection(), $dn, $filter, $fields, $onlyAttributes, $size, $time);
}
/**
* {@inheritdoc}
*/
public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0)
{
return ldap_list($this->getConnection(), $dn, $filter, $fields, $onlyAttributes, $size, $time);
}
/**
* {@inheritdoc}
*/
public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0)
{
return ldap_read($this->getConnection(), $dn, $filter, $fields, $onlyAttributes, $size, $time);
}
/**
* {@inheritdoc}
*/
public function bind($username, $password, $sasl = false)
{
if ($this->isUsingTLS()) {
$this->startTLS();
}
if ($sasl) {
return $this->bound = ldap_sasl_bind($this->getConnection(), null, null, 'GSSAPI');
}
return $this->bound = ldap_bind($this->getConnection(), $username, $password);
}
/**
* {@inheritdoc}
*/
public function add($dn, array $entry)
{
return ldap_add($this->getConnection(), $dn, $entry);
}
/**
* {@inheritdoc}
*/
public function delete($dn)
{
return ldap_delete($this->getConnection(), $dn);
}
/**
* {@inheritdoc}
*/
public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false)
{
return ldap_rename($this->getConnection(), $dn, $newRdn, $newParent, $deleteOldRdn);
}
/**
* {@inheritdoc}
*/
public function modify($dn, array $entry)
{
return ldap_modify($this->getConnection(), $dn, $entry);
}
/**
* {@inheritdoc}
*/
public function modifyBatch($dn, array $values)
{
return ldap_modify_batch($this->getConnection(), $dn, $values);
}
/**
* {@inheritdoc}
*/
public function modAdd($dn, array $entry)
{
return ldap_mod_add($this->getConnection(), $dn, $entry);
}
/**
* {@inheritdoc}
*/
public function modReplace($dn, array $entry)
{
return ldap_mod_replace($this->getConnection(), $dn, $entry);
}
/**
* {@inheritdoc}
*/
public function modDelete($dn, array $entry)
{
return ldap_mod_del($this->getConnection(), $dn, $entry);
}
/**
* {@inheritdoc}
*/
public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = '')
{
if ($this->isPagingSupported()) {
return ldap_control_paged_result($this->getConnection(), $pageSize, $isCritical, $cookie);
}
throw new AdldapException(
'LDAP Pagination is not supported on your current PHP installation.'
);
}
/**
* {@inheritdoc}
*/
public function controlPagedResultResponse($result, &$cookie)
{
if ($this->isPagingSupported()) {
return ldap_control_paged_result_response($this->getConnection(), $result, $cookie);
}
$message = 'LDAP Pagination is not supported on your current PHP installation.';
throw new AdldapException($message);
}
/**
* {@inheritdoc}
*/
public function errNo()
{
return ldap_errno($this->getConnection());
}
/**
* {@inheritdoc}
*/
public function getExtendedError()
{
return $this->getDiagnosticMessage();
}
/**
* {@inheritdoc}
*/
public function getExtendedErrorHex()
{
if (preg_match("/(?<=data\s).*?(?=\,)/", $this->getExtendedError(), $code)) {
return $code[0];
}
}
/**
* {@inheritdoc}
*/
public function getExtendedErrorCode()
{
return $this->extractDiagnosticCode($this->getExtendedError());
}
/**
* {@inheritdoc}
*/
public function err2Str($number)
{
return ldap_err2str($number);
}
/**
* {@inheritdoc}
*/
public function getDiagnosticMessage()
{
ldap_get_option($this->getConnection(), LDAP_OPT_ERROR_STRING, $diagnosticMessage);
return $diagnosticMessage;
}
/**
* {@inheritdoc}
*/
public function extractDiagnosticCode($message)
{
preg_match('/^([\da-fA-F]+):/', $message, $matches);
return isset($matches[1]) ? $matches[1] : false;
}
/**
* Returns the LDAP protocol to utilize for the current connection.
*
* @return string
*/
public function getProtocol()
{
return $this->isUsingSSL() ? $this::PROTOCOL_SSL : $this::PROTOCOL;
}
/**
* Generates an LDAP connection string for each host given.
*
* @param string|array $hosts
* @param string $protocol
* @param string $port
*
* @return string
*/
protected function getConnectionString($hosts = [], $protocol, $port)
{
// Normalize hosts into an array.
$hosts = is_array($hosts) ? $hosts : [$hosts];
$hosts = array_map(function ($host) use ($protocol, $port) {
return "{$protocol}{$host}:{$port}";
}, $hosts);
return implode(' ', $hosts);
}
/**
* Returns true / false if the current
* PHP install supports LDAP.
*
* @return bool
*/
public function isSupported()
{
return function_exists('ldap_connect');
}
/**
* Returns true / false if the current
* PHP install supports an SASL bound
* LDAP connection.
*
* @return bool
*/
public function isSaslSupported()
{
return function_exists('ldap_sasl_bind');
}
/**
* Returns true / false if the current
* PHP install supports LDAP paging.
*
* @return bool
*/
public function isPagingSupported()
{
return function_exists('ldap_control_paged_result');
}
/**
* Returns true / false if the current
* PHP install supports batch modification.
* Requires PHP 5.4 >= 5.4.26, PHP 5.5 >= 5.5.10 or PHP 5.6 >= 5.6.0.
*
* @return bool
*/
public function isBatchSupported()
{
return function_exists('ldap_modify_batch');
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
//namespace userClass;
/**
* Description of userClass
*
* @author Stagiaire
*/
class userClass extends ldapClass {
//put your code here
public function isValid($Usr, $Pwd)
{
if( $Usr == "administrator" && $Pwd == "Pa55w.rd" )
return true;
return false;
}
}

View File

@@ -0,0 +1,8 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/

View File

@@ -0,0 +1,7 @@
<?php
$Cfg = ['host' => 'dc',
'user' => 'Administraor',
'pass' => 'P55w.rd',
'base' => 'dc=easylinux,dc=lan'
];

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,65 @@
body {
background-color: white;
}
#loginbox {
margin-top: 30px;
}
#loginbox > div:first-child {
padding-bottom: 10px;
}
.iconmelon {
display: block;
margin: auto;
}
#form > div {
margin-bottom: 25px;
}
#form > div:last-child {
margin-top: 10px;
margin-bottom: 10px;
}
.panel {
background-color: ffffff;
}
.panel-body {
padding-top: 30px;
background-color: rgba(2555,255,255,.3);
}
#particles {
width: 100%;
height: 100%;
overflow: hidden;
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
z-index: -2;
}
.iconmelon,
.im {
position: relative;
width: 150px;
height: 150px;
display: block;
fill: #525151;
}
.iconmelon:after,
.im:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1 @@

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,27 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Exit program (logout)
*
*/
function Quit()
{
document.getElementById('Action').value='Logout';
document.getElementById('formAction').submit();
}
$(function() {
$('#jsTree').jstree({
'core' : {
'data' : {
"url" : "src/ajax.php?jstree=1",
"data" : function (node) {
return { "id" : node.id };
}
}
}
});
});

View File

@@ -0,0 +1,6 @@
Quit()
------
Exit program (logout)

View File

@@ -0,0 +1,4 @@
</body>
</html>

View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- favicon -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<title>{$Title}</title>
<link href="vendor/components/jqueryui/themes/base/jquery-ui.min.css" rel="stylesheet" />
<link href="vendor/twbs/bootstrap/dist/css/bootstrap.css" rel="stylesheet">
<link href="src/css/style.css" rel="stylesheet">
<meta name="generator" content="Hand Made" >
<meta name="author" content="Serge NOEL" >
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8">
<meta http-equiv="expires" content="0">
<script src="vendor/components/jquery/jquery.js"></script>
<script src="vendor/components/jqueryui/jquery-ui.js"></script>
<script src="vendor/twbs/bootstrap/dist/js/bootstrap.js"></script>
<script src="vendor/vakata/jstree/src/jstree.js"></script>

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<!-- favicon -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{$Title}</title>
<meta name="description" content="Gestion annuaire">
<meta name="author" content="Serge NOEL">
<link href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="vendor/components/jquery/jquery.js" type="text/javascript"></script>
<link href="src/css/login.css" rel="stylesheet">
<script src="src/javascript/login.js" type="text/javascript"></script>
</head>
{if isset($error) }
<body onload="onLoad();">
{else}
<body >
{/if}
<div class="container">
<!-- <div style="float: left"><img src="src/assets/Favicon.png" width="256" alt="Logo"></div> -->
<div id="loginbox" class="mainbox col-md-4 col-md-offset-4 col-sm-6 col-sm-offset-3">
<div class="panel panel-default" >
<div class="panel-heading">
<div class="panel-title text-center">AD Access</div>
</div>
<div class="panel-body" >
<form name="form" id="form" class="form-horizontal" enctype="multipart/form-data" method="POST" action='index.php'>
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input name="sLogin" id="sLogin" type="text" class="form-control" value="" placeholder="User">
</div>
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="sPassword" type="password" class="form-control" name="sPassword" placeholder="Password">
</div>
<div class="form-group">
<!-- Button -->
<div class="col-sm-12 controls">
<button type="submit" href="#" class="btn btn-primary pull-right"><i class="glyphicon glyphicon-log-in"></i> Log in</button>
</div>
</div>
<input type='hidden' id='Action' name='Action' value='tryLogin' />
</form>
</div>
</div>
</div>
{if isset($error) }
<div class="col-md-12">&nbsp;</div>
<div class="col-md-12" id='bAlert'>
<div class="alert alert-dismissable alert-danger">
<h4>{$error}</h4>
</div>
</div>
{/if}
</div>
<script type='text/javascript'>
</script>
</body>
</html>

View File

@@ -0,0 +1,62 @@
{include file='header.smarty'}
<script src="src/javascript/main.js"></script>
</head>
<body>
<form action='index.php' id='formAction' method='post'>
<div class="container">
<!-- Boîte modale de type Popup -->
<div class="modal fade" id="popModal">
<div class="modal-header">
<a class="close" data-dismiss="modal">&times;&nbsp;&nbsp;</a>
<h3 id="popTitle"></h3>
</div>
<div class="modal-body" id="popContent">
</div>
<div class="modal-footer">
<a href="#" class="btn" data-dismiss="modal" id='popClose'>Fermer</a>
<a href="#" class="btn btn-primary" id="popAction"
id='popAction' onClick='myValid();' >Enregistrer</a>
</div>
</div>
<!-- /Boîte modale de type Popup -->
<!-- Menu de l'application -->
<nav class="navbar navbar-default">
<ul class="nav navbar-nav">
<li><a href="#" onClick='Quit();' id='Logout'>D&eacute;connection</a> </li>
<!-- <li class="dropdown">
<a data-toggle="dropdown" href="#" id='menuItem'>Articles<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a onClick='jsfAddItem();' href="#" id='menuAddItem' >Créer</a></li>
<li><a onClick='jsfModItem();' href="#" id='menuModItem'>Modifier</a></li>
<li><a onClick='jsfDelItem();' href="#" id='menuDelItem'>Supprimer</a></li>
<li class="divider"></li>
<li><a onClick='jsfAddStock();' href="#" id='menuAddStock'>Ajout stock</a></li>
<li><a onClick='jsfDelStock();' href="#" id='menuDelStock'>Supp. stock</a></li>
</ul>
</li>
<li> <a href="#" onClick='jsfInventory();'>Inventaire</a> </li> -->
</ul>
</nav>
<!-- /Menu de l'application -->
</div> <!-- /container -->
<div class="col-md-12" id='jsTree'>&nbsp;</div>
<input type='hidden' name='Action' id='Action' value='' />
</form>
<!-- Boîte d'affichage d'erreur -->
<div class="col-md-12">&nbsp;</div>
<div class="col-md-12" id='bAlert' style='display: none'>
<div class="alert alert-dismissable alert-danger">
<h4>{{ error }}</h4>
</div>
</div>
<!-- /Boîte d'affichage d'erreur -->
{include file='footer.smarty' }