--- /dev/null
+<?php
+ class ExploitantsController extends AppController {
+ public $helpers = array('Html', 'Form');
+ public $components = array('RequestHandler');
+
+ public function index() {
+ //$this->set('exploitants', $this->Exploitant->find('all'));
+ $exploitants = $this->Exploitant->find('all');
+ $this->set(array(
+ 'exploitants' => $exploitants,
+ '_serialize' => array('exploitants')
+ ));
+ }
+
+ public function view($id = null) {
+ if (!$id) {
+ throw new NotFoundException(__('Mauvais exploitant'));
+ }
+
+ $exploitant = $this->Exploitant->findById($id);
+ if (!$exploitant) {
+ throw new NotFoundException(__('Mauvais exploitant'));
+ }
+ $this->set('exploitant', $exploitant);
+ }
+
+ public function add() {
+ if ($this->request->is('exploitant')) {
+ $this->Exploitant->create();
+ if ($this->Exploitant->save($this->request->data)) {
+ $this->Session->setFlash(__("L'exploitant a été enregistré."));
+ return $this->redirect(array('action' => 'index'));
+ }
+ $this->Session->setFlash(__("Enregistrement de l'exploitant impossible."));
+ }
+ }
+
+ public function edit($id = null) {
+ if (!$id) {
+ throw new NotFoundException(__('Exploitant introuvable'));
+ }
+
+ $exploitant = $this->Exploitant->findById($id);
+ if (!$exploitant) {
+ throw new NotFoundException(__('Exploitant introuvable'));
+ }
+ $this->set('exploitant', $exploitant);
+
+ $produits_id = explode("|", $this->Exploitant->produits);
+ $produits = [];
+
+ /*
+ foreach ($produits_id as $produit_id) {
+ $produits += $this->Produit->findById($produit_id);
+ }
+ */
+ $this->set('produits', $produits);
+
+ if ($this->request->is(array('exploitant', 'put'))) {
+ $this->Exploitant->id = $id;
+ if ($this->Exploitant->save($this->request->data)) {
+ $this->Session->setFlash(__("L'exploitant a été mis à jour."));
+ return $this->redirect(array('action' => 'index'));
+ }
+ $this->Session->setFlash(__("Mise à jour de l'exploitant impossible."));
+ }
+
+ if (!$this->request->data) {
+ $this->request->data = $exploitant;
+ }
+ }
+
+ public function delete($id) {
+ if ($this->request->is('get')) {
+ throw new MethodNotAllowedException();
+ }
+
+ if ($this->Exploitant->delete($id)) {
+ $this->Session->setFlash(
+ __("L'exploitant d'id: %s a été supprimé.", h($id))
+ );
+ return $this->redirect(array('action' => 'index'));
+ }
+ }
+ }
+?>
--- /dev/null
+<?php
+ class Exploitant extends AppModel {
+ public $validate = array(
+ 'reference' => array(
+ 'rule' => 'notEmpty'
+ )
+ );
+ }
+?>
--- /dev/null
+<h1>Ajout d'un exploitant</h1>
+<?php
+ echo $this->Form->create('Exploitant');
+ echo $this->Form->input('nom');
+ echo $this->Form->input('reference');
+ echo $this->Form->input('produits');
+ echo $this->Form->end("Enregistrer l'exploitant");
+?>
\ No newline at end of file
--- /dev/null
+<h1>Editer l'exploitant</h1>
+<?php
+ echo $this->Form->create('Exploitant');
+ echo $this->Form->input('nom');
+ echo $this->Form->input('reference');
+ echo $this->Form->input('produits');
+ foreach ($produits as $produit) {
+ echo h($produit['Produit']['nom']);
+ }
+ echo h($exploitant['Exploitant']['produits']);
+ echo $this->Form->input('id', array('type' => 'hidden'));
+ echo $this->Form->end("Mettre à jour l'exploitant");
+?>
\ No newline at end of file
--- /dev/null
+<h1>Liste d'exploitants</h1>
+<table>
+ <tr>
+ <th>Nom</th>
+ <th>Référence</th>
+ </tr>
+
+ <?php foreach ($exploitants as $exploitant): ?>
+ <tr>
+ <td>
+ <?php echo $this->Html->link(
+ $exploitant['Exploitant']['nom'],
+ array('controller' => 'exploitants', 'action' => 'edit', $exploitant['Exploitant']['id'])
+ );
+ ?>
+ </td>
+ <td><?php echo $exploitant['Exploitant']['reference']; ?></td>
+ <td>
+ <?php
+ echo $this->Form->postLink(
+ 'Supprimer',
+ array('action' => 'delete', $exploitant['Exploitant']['id']),
+ array('confirm' => 'Etes-vous certain ?')
+ );
+ ?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ <?php unset($exploitant); ?>
+ <?php echo $this->Html->link(
+ 'Ajouter un exploitant',
+ array('controller' => 'exploitants', 'action' => 'add')
+ ); ?>
+</table>
--- /dev/null
+<h1>Nom : <?php echo h($exploitant['Exploitant']['nom']); ?></h1>
+
+<p>Reference : <?php echo h($exploitant['Exploitant']['reference']); ?></p>
+
+<p>Produits : <?php echo h($exploitant['Exploitant']['exploitants']); ?></p>
-<h1>Add Post</h1>
+<h1>Ajout d'un produit</h1>
<?php
echo $this->Form->create('Produit');
echo $this->Form->input('nom');
<?php
echo $this->Form->create('Produit');
echo $this->Form->input('nom');
-echo $this->Form->input('version');
echo $this->Form->input('reference');
-echo $this->Form->input('fqdn_interne');
-echo $this->Form->input('fqdn_externe');
-echo $this->Form->input('clients');
-// TO-DO : Liste des clients + liens vers client
echo $this->Form->input('exploitant');
-echo $this->Form->input('systeme');
-echo $this->Form->input('uid');
+echo $this->Form->input('version');
+echo $this->Form->input('fqdn_interne');
+//echo $this->Form->input('fqdn_externe');
+//echo $this->Form->input('systeme');
+//echo $this->Form->input('uid');
echo $this->Form->input('id', array('type' => 'hidden'));
echo $this->Form->end('Mettre à jour le produit');
?>
\ No newline at end of file
--- /dev/null
+###### CONFIGURATION ALLO AGENT ######
+
+# REFERENCE INSTANCE APPLICATION SUR ALLO = NOM FICHE INSTALL SUGAR = NOM PRODUIT / REF CLIENT + TYPE + DATE (AAAAMMJJhhmm)
+
+# Client classique
+produit_reference="IP/CCLEZI_PROD201309250000"
+
+# Type d'usager (exploitant|client)
+usager_type="client"
+
+# Type d'instance du produit (qualif|prod) -> inutile avec reference ?
+produit_type="prod"
+
+# Fqdn interne
+#produit.fqdn.interne="parapheur.test.adullact.org:8080/alfresco/service" # I-PARAPHEUR
+#produit.fqdn.interne="asalaedev.asalae.dev.adullact.org" # AS@LAE
+produit_fqdn_interne="api_test"
+
+# Fqdn externe
+#produit.fqdn.externe=""
+
+# ALLO Serveur
+allo_serveur_url="allo_serveur"
+
+## Configuration du header http
+# Type de données acceptées
+response_accept="Accept: application/json"
+# Type de données envoyées
+request_type="Content-Type: application/json"
+
+# Logs
+log_file="allo_agent.log"
--- /dev/null
+HTTP/1.1 200 OK\r
+Date: Mon, 26 Jan 2015 16:44:33 GMT\r
+Server: Apache/2.4.6 (Ubuntu)\r
+X-Powered-By: PHP/5.5.3-1ubuntu2.6\r
+Access-Control-Allow-Origin: *\r
+Content-Length: 5\r
+Content-Type: text/html; charset=utf-8\r
+\r
+PROUT
--- /dev/null
+#!/bin/bash
+
+# FICHIER DE CONFIGURATION
+source ./allo_agent.conf
+
+# CLEAN DES LOGS
+if [ -e "${log_file}" ]
+then
+ rm "${log_file}"
+fi
+
+# TEST DE CONNEXION
+code=$(curl -s -w "%{http_code}" --max-time 5 --output /dev/null "http://${produit_fqdn_interne}/api/rest/allo/version")
+echo ${produit_fqdn_interne}
+echo ${code}
+
+if [ "${code}" == 200 ] || [ "${code}" == 301 ]
+then
+ # REQUETE (en insecure pour le moment)
+ curl --max-time 10 -k -X GET -H "${response_accept}" "http://${produit_fqdn_interne}/api/rest/allo/version/" --output "response.json" 2> /dev/null
+
+ # LOG DE LA REPONSE
+ #echo "$(cat response.json)" 2>&1 | tee -a $log_file
+
+ # VALIDATION DU JSON (nécessite outil de validation json)
+ isJSONCorrupted=$(cat response.json | module/json -nq)
+
+ # SI LA VARIABLE EST INITIALISEE MAIS VIDE => PAS D'ERREUR
+ if [[ -z $isJSONCorrupted && ${isJSONCorrupted+x} ]]
+ then
+ # AJOUT DE LA REFERENCE PRODUIT (nécessite package jq)
+ jq '. + { "reference": "'"${produit_reference}"'" }' response.json > tmp.json
+
+ # AJOUT DU TYPE D'USAGER
+ jq '. + { "usager_type": "'"${usager_type}"'" }' tmp.json > request.json
+
+ # ENVOI DE L'UPDATE AU SERVEUR
+ curl -k -X PUT -H "${request_type}" -d "$(cat request.json)" -i "http://${allo_serveur_url}/?action=upload_info" --output "response_server" 2> /dev/null
+ if [ -e ./response_server ]
+ then
+ echo "$(cat response_server)" 2>&1 | tee -a $log_file
+ else
+ echo "Aucune réponse du serveur !" 2>&1 | tee -a $log_file
+ fi
+ rm response*
+ rm request.json
+ rm tmp.json
+ else
+ echo "Les données récupérées sont illisibles" 2>&1 | tee -a $log_file
+ fi
+else
+ echo "L'application a renvoyé une erreur : " 2>&1 | tee -a $log_file
+ case "${code}" in
+ "500")
+ echo "Erreur interne du serveur" 2>&1 | tee -a $log_file
+ ;;
+ "400" | "404")
+ echo "Mauvaise requete" 2>&1 | tee -a $log_file
+ ;;
+ *)
+ echo "Aucune réponse de l'application" 2>&1 | tee -a $log_file
+ ;;
+ esac
+fi
--- /dev/null
+#!/usr/bin/env node
+/**
+ * Copyright (c) 2014 Trent Mick. All rights reserved.
+ * Copyright (c) 2014 Joyent Inc. All rights reserved.
+ *
+ * json -- JSON love for your command line.
+ *
+ * See <https://github.com/trentm/json> and <https://trentm.com/json/>
+ */
+
+var VERSION = '9.0.3';
+
+var p = console.warn;
+var util = require('util');
+var assert = require('assert');
+var path = require('path');
+var vm = require('vm');
+var fs = require('fs');
+var warn = console.warn;
+var EventEmitter = require('events').EventEmitter;
+
+
+
+//--- exports for module usage
+
+exports.main = main;
+exports.getVersion = getVersion;
+exports.parseLookup = parseLookup;
+
+// As an exported API, these are still experimental:
+exports.lookupDatum = lookupDatum;
+exports.printDatum = printDatum; // DEPRECATED
+
+
+
+//---- globals and constants
+
+// Output modes.
+var OM_JSONY = 1;
+var OM_JSON = 2;
+var OM_INSPECT = 3;
+var OM_COMPACT = 4;
+var OM_FROM_NAME = {
+ 'jsony': OM_JSONY,
+ 'json': OM_JSON,
+ 'inspect': OM_INSPECT,
+ 'compact': OM_COMPACT
+}
+
+
+
+//---- support functions
+
+function getVersion() {
+ return VERSION;
+}
+
+/**
+ * Return a *shallow* copy of the given object.
+ *
+ * Only support objects that you get out of JSON, i.e. no functions.
+ */
+function objCopy(obj) {
+ var copy;
+ if (Array.isArray(obj)) {
+ copy = obj.slice();
+ } else if (typeof (obj) === 'object') {
+ copy = {};
+ Object.keys(obj).forEach(function (k) {
+ copy[k] = obj[k];
+ });
+ } else {
+ copy = obj; // immutable type
+ }
+ return copy;
+}
+
+if (util.format) {
+ format = util.format;
+} else {
+ // From <https://github.com/joyent/node/blob/master/lib/util.js#L22>:
+ var formatRegExp = /%[sdj%]/g;
+
+ function format(f) {
+ if (typeof (f) !== 'string') {
+ var objects = [];
+ for (var i = 0; i < arguments.length; i++) {
+ objects.push(util.inspect(arguments[i]));
+ }
+ return objects.join(' ');
+ }
+ var i = 1;
+ var args = arguments;
+ var len = args.length;
+ var str = String(f).replace(formatRegExp, function (x) {
+ if (i >= len)
+ return x;
+ switch (x) {
+ case '%s':
+ return String(args[i++]);
+ case '%d':
+ return Number(args[i++]);
+ case '%j':
+ return JSON.stringify(args[i++]);
+ case '%%':
+ return '%';
+ default:
+ return x;
+ }
+ });
+ for (var x = args[i]; i < len; x = args[++i]) {
+ if (x === null || typeof (x) !== 'object') {
+ str += ' ' + x;
+ } else {
+ str += ' ' + util.inspect(x);
+ }
+ }
+ return str;
+ };
+}
+
+/**
+ * Parse the given string into a JS string. Basically: handle escapes.
+ */
+function _parseString(s) {
+ /* JSSTYLED */
+ var quoted = '"' + s.replace(/\\"/, '"').replace('"', '\\"') + '"';
+ return eval(quoted);
+}
+
+// json_parse.js (<https://github.com/douglascrockford/JSON-js>)
+/* BEGIN JSSTYLED */
+// START json_parse
+var json_parse=function(){"use strict";var a,b,c={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"\t"},d,e=function(b){throw{name:"SyntaxError",message:b,at:a,text:d}},f=function(c){return c&&c!==b&&e("Expected '"+c+"' instead of '"+b+"'"),b=d.charAt(a),a+=1,b},g=function(){var a,c="";b==="-"&&(c="-",f("-"));while(b>="0"&&b<="9")c+=b,f();if(b==="."){c+=".";while(f()&&b>="0"&&b<="9")c+=b}if(b==="e"||b==="E"){c+=b,f();if(b==="-"||b==="+")c+=b,f();while(b>="0"&&b<="9")c+=b,f()}a=+c;if(!isFinite(a))e("Bad number");else return a},h=function(){var a,d,g="",h;if(b==='"')while(f()){if(b==='"')return f(),g;if(b==="\\"){f();if(b==="u"){h=0;for(d=0;d<4;d+=1){a=parseInt(f(),16);if(!isFinite(a))break;h=h*16+a}g+=String.fromCharCode(h)}else if(typeof c[b]=="string")g+=c[b];else break}else g+=b}e("Bad string")},i=function(){while(b&&b<=" ")f()},j=function(){switch(b){case"t":return f("t"),f("r"),f("u"),f("e"),!0;case"f":return f("f"),f("a"),f("l"),f("s"),f("e"),!1;case"n":return f("n"),f("u"),f("l"),f("l"),null}e("Unexpected '"+b+"'")},k,l=function(){var a=[];if(b==="["){f("["),i();if(b==="]")return f("]"),a;while(b){a.push(k()),i();if(b==="]")return f("]"),a;f(","),i()}}e("Bad array")},m=function(){var a,c={};if(b==="{"){f("{"),i();if(b==="}")return f("}"),c;while(b){a=h(),i(),f(":"),Object.hasOwnProperty.call(c,a)&&e('Duplicate key "'+a+'"'),c[a]=k(),i();if(b==="}")return f("}"),c;f(","),i()}}e("Bad object")};return k=function(){i();switch(b){case"{":return m();case"[":return l();case'"':return h();case"-":return g();default:return b>="0"&&b<="9"?g():j()}},function(c,f){var g;return d=c,a=0,b=" ",g=k(),i(),b&&e("Syntax error"),typeof f=="function"?function h(a,b){var c,d,e=a[b];if(e&&typeof e=="object")for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=h(e,c),d!==undefined?e[c]=d:delete e[c]);return f.call(a,b,e)}({"":g},""):g}}();
+// END json_parse
+/* END JSSTYLED */
+
+function printHelp() {
+ /* BEGIN JSSTYLED */
+ var w = console.log;
+ w('Usage:');
+ w(' <something generating JSON on stdout> | json [OPTIONS] [LOOKUPS...]');
+ w(' json -f FILE [OPTIONS] [LOOKUPS...]');
+ w('');
+ w('Pipe in your JSON for pretty-printing, JSON validation, filtering, ');
+ w('and modification. Supply one or more `LOOKUPS` to extract a ');
+ w('subset of the JSON. HTTP header blocks are skipped by default.');
+ w('Roughly in order of processing, features are:');
+ w('');
+ w('Grouping:');
+ w(' Use "-g" or "--group" to group adjacent objects, separated by');
+ w(' by no space or a by a newline, or adjacent arrays, separate by');
+ w(' by a newline. This can be helpful for, e.g.: ');
+ w(' $ cat *.json | json -g ... ');
+ w(' and similar.');
+ w('');
+ w('Execution:');
+ w(' Use the "-e CODE" option to execute JavaScript code on the input JSON.');
+ w(' $ echo \'{"name":"trent","age":38}\' | json -e \'this.age++\'');
+ w(' {');
+ w(' "name": "trent",');
+ w(' "age": 39');
+ w(' }');
+ w(' If input is an array, this will automatically process each');
+ w(' item separately.');
+ w('');
+ w('Conditional filtering:');
+ w(' Use the "-c CODE" option to filter the input JSON.');
+ w(' $ echo \'[{"age":38},{"age":4}]\' | json -c \'this.age>21\'');
+ w(' [{\'age\':38}]');
+ w(' If input is an array, this will automatically process each');
+ w(' item separately. Note: "CODE" is JavaScript code.');
+ w('');
+ w('Lookups:');
+ w(' Use lookup arguments to extract particular values:');
+ w(' $ echo \'{"name":"trent","age":38}\' | json name');
+ w(' trent');
+ w('');
+ w(' Use "-a" for *array processing* of lookups and *tabular output*:');
+ w(' $ echo \'{"name":"trent","age":38}\' | json name age');
+ w(' trent');
+ w(' 38');
+ w(' $ echo \'[{"name":"trent","age":38},');
+ w(' {"name":"ewan","age":4}]\' | json -a name age');
+ w(' trent 38');
+ w(' ewan 4');
+ w('');
+ w('In-place editing:');
+ w(' Use "-I, --in-place" to edit a file in place:');
+ w(' $ json -I -f config.json # reformat');
+ w(' $ json -I -f config.json -c \'this.logLevel="debug"\' # add field');
+ w('');
+ w('Pretty-printing:');
+ w(' Output is "jsony" by default: 2-space indented JSON, except a');
+ w(' single string value is printed without quotes.');
+ w(' $ echo \'{"name": "trent", "age": 38}\' | json');
+ w(' {');
+ w(' "name": "trent",');
+ w(' "age": 38');
+ w(' }');
+ w(' $ echo \'{"name": "trent", "age": 38}\' | json name');
+ w(' trent');
+ w('');
+ w(" Use '-j' or '-o json' for explicit JSON, '-o json-N' for N-space indent:");
+ w(' $ echo \'{"name": "trent", "age": 38}\' | json -o json-0');
+ w(' {"name":"trent","age":38}');
+ w('');
+ w('Options:');
+ w(' -h, --help Print this help info and exit.');
+ w(' --version Print version of this command and exit.');
+ w(' -q, --quiet Don\'t warn if input isn\'t valid JSON.');
+ w('');
+ w(' -f FILE Path to a file to process. If not given, then');
+ w(' stdin is used.');
+ w(' -I, --in-place In-place edit of the file given with "-f".');
+ w(' Lookups are not allow with in-place editing');
+ w(' because it makes it too easy to lose content.');
+ w('');
+ w(' -H Drop any HTTP header block (as from `curl -i ...`).');
+ w(' -g, --group Group adjacent objects or arrays into an array.');
+ w(' --merge Merge adjacent objects into one. Keys in last ');
+ w(' object win.');
+ w(' --deep-merge Same as "--merge", but will recurse into objects ');
+ w(' under the same key in both.')
+ w(' -a, --array Process input as an array of separate inputs');
+ w(' and output in tabular form.');
+ w(' -A Process input as a single object, i.e. stop');
+ w(' "-e" and "-c" automatically processing each');
+ w(' item of an input array.');
+ w(' -d DELIM Delimiter char for tabular output (default is " ").');
+ w(' -D DELIM Delimiter char between lookups (default is "."). E.g.:');
+ w(' $ echo \'{"a.b": {"b": 1}}\' | json -D / a.b/b');
+ w('');
+ w(' -M, --items Itemize an object into an array of ');
+ w(' {"key": <key>, "value": <value>}');
+ w(' objects for easier processing.');
+ w('');
+ w(' -e CODE Execute the given JavaScript code on the input. If input');
+ w(' is an array, then each item of the array is processed');
+ w(' separately (use "-A" to override).');
+ w(' -c CODE Filter the input with JavaScript `CODE`. If `CODE`');
+ w(' returns false-y, then the item is filtered out. If');
+ w(' input is an array, then each item of the array is ');
+ w(' processed separately (use "-A" to override).');
+ w('');
+ w(' -k, --keys Output the input object\'s keys.');
+ w(' -n, --validate Just validate the input (no processing or output).');
+ w(' Use with "-q" for silent validation (exit status).');
+ w('');
+ w(' -o, --output MODE');
+ w(' Specify an output mode. One of:');
+ w(' jsony (default): JSON with string quotes elided');
+ w(' json: JSON output, 2-space indent');
+ w(' json-N: JSON output, N-space indent, e.g. "json-4"');
+ w(' inspect: node.js `util.inspect` output');
+ w(' -i Shortcut for `-o inspect`');
+ w(' -j Shortcut for `-o json`');
+ w(' -0, -2, -4 Set indentation to the given value w/o setting MODE.');
+ w(' -0 => -o jsony-0');
+ w(' -4 => -o jsony-4');
+ w(' -j0 => -o json-0');
+ w('');
+ w('See <http://trentm.com/json> for more docs and ');
+ w('<https://github.com/trentm/json> for project details.');
+ /* END JSSTYLED */
+}
+
+
+/**
+ * Parse the command-line options and arguments into an object.
+ *
+ * {
+ * 'args': [...] // arguments
+ * 'help': true, // true if '-h' option given
+ * // etc.
+ * }
+ *
+ * @return {Object} The parsed options. `.args` is the argument list.
+ * @throws {Error} If there is an error parsing argv.
+ */
+function parseArgv(argv) {
+ var parsed = {
+ args: [],
+ help: false,
+ quiet: false,
+ dropHeaders: false,
+ exeSnippets: [],
+ condSnippets: [],
+ outputMode: OM_JSONY,
+ jsonIndent: 2,
+ array: null,
+ delim: ' ',
+ lookupDelim: '.',
+ items: false,
+ outputKeys: false,
+ group: false,
+ merge: null, // --merge -> 'shallow', --deep-merge -> 'deep'
+ inputFiles: [],
+ validate: false,
+ inPlace: false
+ };
+
+ // Turn '-iH' into '-i -H', except for argument-accepting options.
+ var args = argv.slice(2); // drop ['node', 'scriptname']
+ var newArgs = [];
+ var optTakesArg = {
+ 'd': true,
+ 'o': true,
+ 'D': true
+ };
+ for (var i = 0; i < args.length; i++) {
+ if (args[i] === '--') {
+ newArgs = newArgs.concat(args.slice(i));
+ break;
+ }
+ if (args[i].charAt(0) === '-' && args[i].charAt(1) !== '-' &&
+ args[i].length > 2)
+ {
+ var splitOpts = args[i].slice(1).split('');
+ for (var j = 0; j < splitOpts.length; j++) {
+ newArgs.push('-' + splitOpts[j])
+ if (optTakesArg[splitOpts[j]]) {
+ var optArg = splitOpts.slice(j + 1).join('');
+ if (optArg.length) {
+ newArgs.push(optArg);
+ }
+ break;
+ }
+ }
+ } else {
+ newArgs.push(args[i]);
+ }
+ }
+ args = newArgs;
+
+ endOfOptions = false;
+ while (args.length > 0) {
+ var arg = args.shift();
+ if (endOfOptions) {
+ parsed.args.push(arg);
+ break;
+ }
+ switch (arg) {
+ case '--':
+ endOfOptions = true;
+ break;
+ case '-h': // display help and exit
+ case '--help':
+ parsed.help = true;
+ break;
+ case '--version':
+ parsed.version = true;
+ break;
+ case '-q':
+ case '--quiet':
+ parsed.quiet = true;
+ break;
+ case '-H': // drop any headers
+ parsed.dropHeaders = true;
+ break;
+ case '-o':
+ case '--output':
+ var name = args.shift();
+ if (!name) {
+ throw new Error('no argument given for "-o|--output" option');
+ }
+ var idx = name.lastIndexOf('-');
+ if (idx !== -1) {
+ var indent = name.slice(idx + 1);
+ if (/^\d+$/.test(indent)) {
+ parsed.jsonIndent = Number(indent);
+ name = name.slice(0, idx);
+ } else if (indent === 'tab') {
+ parsed.jsonIndent = '\t';
+ name = name.slice(0, idx);
+ }
+ }
+ parsed.outputMode = OM_FROM_NAME[name];
+ if (parsed.outputMode === undefined) {
+ throw new Error('unknown output mode: "' + name + '"');
+ }
+ break;
+ case '-0':
+ parsed.jsonIndent = 0;
+ break;
+ case '-2':
+ parsed.jsonIndent = 2;
+ break;
+ case '-4':
+ parsed.jsonIndent = 4;
+ break;
+ case '-I':
+ case '--in-place':
+ parsed.inPlace = true;
+ break;
+ case '-i': // output with util.inspect
+ parsed.outputMode = OM_INSPECT;
+ break;
+ case '-j': // output with JSON.stringify
+ parsed.outputMode = OM_JSON;
+ break;
+ case '-a':
+ case '--array':
+ parsed.array = true;
+ break;
+ case '-A':
+ parsed.array = false;
+ break;
+ case '-d':
+ parsed.delim = _parseString(args.shift());
+ break;
+ case '-D':
+ parsed.lookupDelim = args.shift();
+ if (parsed.lookupDelim.length !== 1) {
+ throw new Error(format(
+ 'invalid lookup delim "%s" (must be a single char)',
+ parsed.lookupDelim));
+ }
+ break;
+ case '-e':
+ case '-E': // DEPRECATED in v9
+ parsed.exeSnippets.push(args.shift());
+ break;
+ case '-c':
+ case '-C': // DEPRECATED in v9
+ parsed.condSnippets.push(args.shift());
+ break;
+ case '-M':
+ case '--items':
+ parsed.items = true;
+ break;
+ case '-k':
+ case '--keys':
+ parsed.outputKeys = true;
+ break;
+ case '-g':
+ case '--group':
+ parsed.group = true;
+ break;
+ case '--merge':
+ parsed.merge = 'shallow';
+ break;
+ case '--deep-merge':
+ parsed.merge = 'deep';
+ break;
+ case '-f':
+ parsed.inputFiles.push(args.shift());
+ break;
+ case '-n':
+ case '--validate':
+ parsed.validate = true;
+ break;
+ default: // arguments
+ if (!endOfOptions && arg.length > 0 && arg[0] === '-') {
+ throw new Error('unknown option "' + arg + '"');
+ }
+ parsed.args.push(arg);
+ break;
+ }
+ }
+
+ if (parsed.group && parsed.merge) {
+ throw new Error('cannot use -g|--group and --merge options together');
+ }
+ if (parsed.outputKeys && parsed.args.length > 0) {
+ throw new Error(
+ 'cannot use -k|--keys option and lookup arguments together');
+ }
+ if (parsed.inPlace && parsed.inputFiles.length !== 1) {
+ throw new Error('must specify exactly one file with "-f FILE" to ' +
+ 'use -I/--in-place');
+ }
+ if (parsed.inPlace && parsed.args.length > 0) {
+ throw new Error('lookups cannot be specified with in-place editing ' +
+ '(-I/--in-place), too easy to lose content');
+ }
+
+ return parsed;
+}
+
+
+
+/**
+ * Streams chunks from given file paths or stdin.
+ *
+ * @param opts {Object} Parsed options.
+ * @returns {Object} An emitter that emits 'chunk', 'error', and 'end'.
+ * - `emit('chunk', chunk, [obj])` where chunk is a complete block of JSON
+ * ready to parse. If `obj` is provided, it is the already parsed
+ * JSON.
+ * - `emit('error', error)` when an underlying stream emits an error
+ * - `emit('end')` when all streams are done
+ */
+function chunkEmitter(opts) {
+ var emitter = new EventEmitter();
+ var streaming = true;
+ var chunks = [];
+ var leftover = '';
+ var finishedHeaders = false;
+
+ function stripHeaders(s) {
+ // Take off a leading HTTP header if any and pass it through.
+ while (true) {
+ if (s.slice(0, 5) === 'HTTP/') {
+ var index = s.indexOf('\r\n\r\n');
+ var sepLen = 4;
+ if (index == -1) {
+ index = s.indexOf('\n\n');
+ sepLen = 2;
+ }
+ if (index != -1) {
+ if (!opts.dropHeaders) {
+ emit(s.slice(0, index + sepLen));
+ }
+ var is100Continue = (
+ s.slice(0, 21) === 'HTTP/1.1 100 Continue');
+ s = s.slice(index + sepLen);
+ if (is100Continue) {
+ continue;
+ }
+ finishedHeaders = true;
+ }
+ } else {
+ finishedHeaders = true;
+ }
+ break;
+ }
+ //console.warn('stripHeaders done, finishedHeaders=%s', finishedHeaders)
+ return s;
+ }
+
+ function emitChunks(block, emitter) {
+ //console.warn('emitChunks start: block="%s"', block)
+ /* JSSTYLED */
+ var splitter = /(})(\s*\n\s*)?({\s*")/;
+ var leftTrimmedBlock = block.trimLeft();
+ if (leftTrimmedBlock && leftTrimmedBlock[0] !== '{') {
+ // Currently only support streaming consecutive *objects*.
+ streaming = false;
+ chunks.push(block);
+ return '';
+ }
+ /**
+ * Example:
+ * > '{"a":"b"}\n{"a":"b"}\n{"a":"b"}'.split(/(})(\s*\n\s*)?({\s*")/)
+ * [ '{"a":"b"',
+ * '}',
+ * '\n',
+ * '{"',
+ * 'a":"b"',
+ * '}',
+ * '\n',
+ * '{"',
+ * 'a":"b"}' ]
+ */
+ var bits = block.split(splitter);
+ //console.warn('emitChunks: bits (length %d): %j', bits.length, bits);
+ if (bits.length === 1) {
+ /*
+ * An unwanted side-effect of using a regex to find
+ * newline-separated objects *with a regex*, is that we are looking
+ * for the end of one object leading into the start of a another.
+ * That means that we can end up buffering a complete object until
+ * a subsequent one comes in. If the input stream has large delays
+ * between objects, then this is unwanted buffering.
+ *
+ * One solution would be full stream parsing of objects a la
+ * <https://github.com/creationix/jsonparse>. This would nicely
+ * also remove the artibrary requirement that the input stream be
+ * newline separated. jsonparse apparently has some issues tho, so
+ * I don't want to use it right now. It also isn't *small* so not
+ * sure I want to inline it (`json` doesn't have external deps).
+ *
+ * An alternative: The block we have so far one of:
+ * 1. some JSON that we don't support grouping (e.g. a stream of
+ * non-objects),
+ * 2. a JSON object fragment, or
+ * 3. a complete JSON object (with a possible trailing '{')
+ *
+ * If #3, then we can just emit this as a chunk right now.
+ *
+ * TODO(PERF): Try out avoiding the first more complete regex split
+ * for a presumed common case of single-line newline-separated JSON
+ * objects (e.g. a bunyan log).
+ */
+ // An object must end with '}'. This is an early out to avoid
+ // `JSON.parse` which I'm *presuming* is slower.
+ var trimmed = block.split(/\s*\r?\n/)[0];
+ if (trimmed[trimmed.length - 1] === '}') {
+ var obj;
+ try {
+ obj = JSON.parse(block);
+ } catch (e) {
+ /* pass through */
+ }
+ if (obj !== undefined) {
+ // Emit the parsed `obj` to avoid re-parsing it later.
+ emitter.emit('chunk', block, obj);
+ block = '';
+ }
+ }
+ return block;
+ } else {
+ var n = bits.length - 2;
+ var s;
+ s = bits[0] + bits[1];
+ emitter.emit('chunk', s, JSON.parse(s));
+ for (var i = 3; i < n; i += 4) {
+ s = bits[i] + bits[i + 1] + bits[i + 2];
+ emitter.emit('chunk', s, JSON.parse(s));
+ }
+ return bits[n] + bits[n + 1];
+ }
+ }
+
+ function addDataListener(stream) {
+ stream.on('data', function (chunk) {
+ var s = leftover + chunk;
+ if (!finishedHeaders) {
+ s = stripHeaders(s);
+ }
+ if (!finishedHeaders) {
+ leftover = s;
+ } else {
+ if (!streaming) {
+ chunks.push(chunk);
+ return;
+ }
+ leftover = emitChunks(s, emitter);
+ }
+ });
+ }
+
+ if (opts.inputFiles.length > 0) {
+ // Stream each file in order.
+ var i = 0;
+
+ function addErrorListener(file) {
+ file.on('error', function (err) {
+ emitter.emit(
+ 'error',
+ format('could not read "%s": %s', opts.inputFiles[i], e)
+ );
+ });
+ }
+
+ function addEndListener(file) {
+ file.on('end', function () {
+ if (i < opts.inputFiles.length) {
+ var next = opts.inputFiles[i++];
+ var nextFile = fs.createReadStream(next,
+ {encoding: 'utf8'});
+ addErrorListener(nextFile);
+ addEndListener(nextFile);
+ addDataListener(nextFile);
+ } else {
+ if (!streaming) {
+ emitter.emit('chunk', chunks.join(''));
+ } else if (leftover) {
+ leftover = emitChunks(leftover, emitter);
+ emitter.emit('chunk', leftover);
+ }
+ emitter.emit('end');
+ }
+ });
+ }
+ var first = fs.createReadStream(opts.inputFiles[i++],
+ {encoding: 'utf8'});
+ addErrorListener(first);
+ addEndListener(first);
+ addDataListener(first);
+ } else {
+ // Streaming from stdin.
+ var stdin = process.openStdin();
+ stdin.setEncoding('utf8');
+ addDataListener(stdin);
+ stdin.on('end', function () {
+ if (!streaming) {
+ emitter.emit('chunk', chunks.join(''));
+ } else if (leftover) {
+ leftover = emitChunks(leftover, emitter);
+ emitter.emit('chunk', leftover);
+ }
+ emitter.emit('end');
+ });
+ }
+ return emitter;
+}
+
+/**
+ * Get input from either given file paths or stdin. If `opts.inPlace` then
+ * this calls the callback once for each `opts.inputFiles`.
+ *
+ * @param opts {Object} Parsed options.
+ * @param callback {Function} `function (err, content, filename)` where err
+ * is an error string if there was a problem, `content` is the read
+ * content and `filename` is the associated file name from which content
+ * was loaded if applicable.
+ */
+function getInput(opts, callback) {
+ if (opts.inputFiles.length === 0) {
+ // Read from stdin.
+ var chunks = [];
+
+ var stdin = process.openStdin();
+ stdin.setEncoding('utf8');
+ stdin.on('data', function (chunk) {
+ chunks.push(chunk);
+ });
+
+ stdin.on('end', function () {
+ callback(null, chunks.join(''));
+ });
+ } else if (opts.inPlace) {
+ for (var i = 0; i < opts.inputFiles.length; i++) {
+ var file = opts.inputFiles[i];
+ var content;
+ try {
+ content = fs.readFileSync(file, 'utf8');
+ } catch (e) {
+ callback(e, null, file);
+ }
+ if (content) {
+ callback(null, content, file);
+ }
+ }
+ } else {
+ // Read input files.
+ var i = 0;
+ var chunks = [];
+ try {
+ for (; i < opts.inputFiles.length; i++) {
+ chunks.push(fs.readFileSync(opts.inputFiles[i], 'utf8'));
+ }
+ } catch (e) {
+ return callback(
+ format('could not read "%s": %s', opts.inputFiles[i], e));
+ }
+ callback(null, chunks.join(''),
+ (opts.inputFiles.length === 1 ? opts.inputFiles[0] : undefined));
+ }
+}
+
+
+function isInteger(s) {
+ return (s.search(/^-?[0-9]+$/) == 0);
+}
+
+
+/**
+ * Parse a lookup string into a list of lookup bits. E.g.:
+ *
+ * 'a.b.c' -> ["a","b","c"]
+ * 'b["a"]' -> ["b","a"]
+ * 'b["a" + "c"]' -> ["b","ac"]
+ *
+ * Optionally receives an alternative lookup delimiter (other than '.')
+ */
+function parseLookup(lookup, lookupDelim) {
+ var debug = function () {};
+ //var debug = console.warn;
+
+ var bits = [];
+ debug('\n*** ' + lookup + ' ***');
+
+ bits = [];
+ lookupDelim = lookupDelim || '.';
+ var bit = '';
+ var states = [null];
+ var escaped = false;
+ var ch = null;
+ for (var i = 0; i < lookup.length; ++i) {
+ var escaped = (!escaped && ch === '\\');
+ var ch = lookup[i];
+ debug('-- i=' + i + ', ch=' + JSON.stringify(ch) + ' escaped=' +
+ JSON.stringify(escaped));
+ debug('states: ' + JSON.stringify(states));
+
+ if (escaped) {
+ bit += ch;
+ continue;
+ }
+
+ switch (states[states.length - 1]) {
+ case null:
+ switch (ch) {
+ case '"':
+ case '\'':
+ states.push(ch);
+ bit += ch;
+ break;
+ case '[':
+ states.push(ch);
+ if (bit !== '') {
+ bits.push(bit);
+ bit = ''
+ }
+ bit += ch;
+ break;
+ case lookupDelim:
+ if (bit !== '') {
+ bits.push(bit);
+ bit = ''
+ }
+ break;
+ default:
+ bit += ch;
+ break;
+ }
+ break;
+
+ case '[':
+ bit += ch;
+ switch (ch) {
+ case '"':
+ case '\'':
+ case '[':
+ states.push(ch);
+ break;
+ case ']':
+ states.pop();
+ if (states[states.length - 1] === null) {
+ var evaled = vm.runInNewContext(
+ '(' + bit.slice(1, -1) + ')', {}, '<lookup>');
+ bits.push(evaled);
+ bit = ''
+ }
+ break;
+ }
+ break;
+
+ case '"':
+ bit += ch;
+ switch (ch) {
+ case '"':
+ states.pop();
+ if (states[states.length - 1] === null) {
+ bits.push(bit);
+ bit = ''
+ }
+ break;
+ }
+ break;
+
+ case '\'':
+ bit += ch;
+ switch (ch) {
+ case '\'':
+ states.pop();
+ if (states[states.length - 1] === null) {
+ bits.push(bit);
+ bit = ''
+ }
+ break;
+ }
+ break;
+ }
+ debug('bit: ' + JSON.stringify(bit));
+ debug('bits: ' + JSON.stringify(bits));
+ }
+
+ if (bit !== '') {
+ bits.push(bit);
+ bit = ''
+ }
+
+ // Negative-intify: strings that are negative ints we change to a Number for
+ // special handling in `lookupDatum`: Python-style negative array indexing.
+ var negIntPat = /^-\d+$/;
+ for (var i = 0; i < bits.length; i++) {
+ if (negIntPat.test(bits[i])) {
+ bits[i] = Number(bits[i]);
+ }
+ }
+
+ debug(JSON.stringify(lookup) + ' -> ' + JSON.stringify(bits));
+ return bits
+}
+
+
+/**
+ * Parse the given stdin input into:
+ * {
+ * 'error': ... error object if there was an error ...,
+ * 'datum': ... parsed object if content was JSON ...
+ * }
+ *
+ * @param buffer {String} The text to parse as JSON.
+ * @param obj {Object} Optional. Set when in streaming mode to avoid
+ * re-interpretation of `group`. Also avoids reparsing.
+ * @param group {Boolean} Default false. If true, then non-JSON input
+ * will be attempted to be 'arrayified' (see inline comment).
+ * @param merge {Boolean} Default null. Can be 'shallow' or 'deep'. An
+ * attempt will be made to interpret the input as adjacent objects to
+ * be merged, last key wins. See inline comment for limitations.
+ */
+function parseInput(buffer, obj, group, merge) {
+ if (obj) {
+ return {
+ datum: obj
+ };
+ } else if (group) {
+ /**
+ * Special case: Grouping (previously called auto-arrayification)
+ * of unjoined list of objects:
+ * {"one": 1}{"two": 2}
+ * and auto-concatenation of unjoined list of arrays:
+ * ["a", "b"]["c", "d"]
+ *
+ * This can be nice to process a stream of JSON objects generated from
+ * multiple calls to another tool or `cat *.json | json`.
+ *
+ * Rules:
+ * - Only JS objects and arrays. Don't see strong need for basic
+ * JS types right now and this limitation simplifies.
+ * - The break between JS objects has to include a newline:
+ * {"one": 1}
+ * {"two": 2}
+ * or no spaces at all:
+ * {"one": 1}{"two": 2}
+ * I.e., not this:
+ * {"one": 1} {"two": 2}
+ * This condition should be fine for typical use cases and ensures
+ * no false matches inside JS strings.
+ * - The break between JS *arrays* has to include a newline:
+ * ["one", "two"]
+ * ["three"]
+ * The 'no spaces' case is NOT supported for JS arrays as of v6.0.0
+ * because <https://github.com/trentm/json/issues/55> shows that that
+ * is not safe.
+ */
+ var newBuffer = buffer;
+ /* JSSTYLED */
+ [/(})\s*\n\s*({)/g, /(})({")/g].forEach(function (pat) {
+ newBuffer = newBuffer.replace(pat, '$1,\n$2');
+ });
+ [/(\])\s*\n\s*(\[)/g].forEach(function (pat) {
+ newBuffer = newBuffer.replace(pat, ',\n');
+ });
+ newBuffer = newBuffer.trim();
+ if (newBuffer[0] !== '[') {
+ newBuffer = '[\n' + newBuffer;
+ }
+ if (newBuffer.slice(-1) !== ']') {
+ newBuffer = newBuffer + '\n]\n';
+ }
+ try {
+ return {
+ datum: JSON.parse(newBuffer)
+ };
+ } catch (e2) {
+ return {
+ error: e2
+ };
+ }
+ } else if (merge) {
+ // See the 'Rules' above for limitations on boundaries for 'adjacent'
+ // objects: KISS.
+ var newBuffer = buffer;
+ /* JSSTYLED */
+ [/(})\s*\n\s*({)/g, /(})({")/g].forEach(function (pat) {
+ newBuffer = newBuffer.replace(pat, '$1,\n$2');
+ });
+ newBuffer = '[\n' + newBuffer + '\n]\n';
+ var objs;
+ try {
+ objs = JSON.parse(newBuffer);
+ } catch (e) {
+ return {
+ error: e
+ };
+ }
+ var merged = objs[0];
+ if (merge === 'shallow') {
+ for (var i = 1; i < objs.length; i++) {
+ var obj = objs[i];
+ Object.keys(obj).forEach(function (k) {
+ merged[k] = obj[k];
+ });
+ }
+ } else if (merge === 'deep') {
+ function deepExtend(a, b) {
+ Object.keys(b).forEach(function (k) {
+ if (a[k] && b[k] &&
+ toString.call(a[k]) === '[object Object]' &&
+ toString.call(b[k]) === '[object Object]')
+ {
+ deepExtend(a[k], b[k])
+ } else {
+ a[k] = b[k];
+ }
+ });
+ }
+ for (var i = 1; i < objs.length; i++) {
+ deepExtend(merged, objs[i]);
+ }
+ } else {
+ throw new Error(format('unknown value for "merge": "%s"', merge));
+ }
+ return {
+ datum: merged
+ };
+ } else {
+ try {
+ return {
+ datum: JSON.parse(buffer)
+ };
+ } catch (e) {
+ return {
+ error: e
+ };
+ }
+ }
+}
+
+
+/**
+ * Apply a lookup to the given datum.
+ *
+ * @argument datum {Object}
+ * @argument lookup {Array} The parsed lookup (from
+ * `parseLookup(<string>, <string>)`). Might be empty.
+ * @returns {Object} The result of the lookup.
+ */
+function lookupDatum(datum, lookup) {
+ var d = datum;
+ for (var i = 0; i < lookup.length; i++) {
+ var bit = lookup[i];
+ if (typeof (bit) === 'number' && bit < 0) {
+ d = d[d.length + bit];
+ } else {
+ d = d[bit];
+ }
+ if (d === undefined) {
+ return undefined;
+ }
+ }
+ return d;
+}
+
+
+/**
+ * Output the given datasets.
+ *
+ * @param datasets {Array} Array of data sets to print, in the form:
+ * `[ [<datum>, <sep>, <alwaysPrintSep>], ... ]`
+ * @param filename {String} The filename to which to write the output. If
+ * not set, then emit to stdout.
+ * @param headers {String} The HTTP header block string, if any, to emit
+ * first.
+ * @param opts {Object} Parsed tool options.
+ */
+function printDatasets(datasets, filename, headers, opts) {
+ var isTTY = (filename ? false : process.stdout.isTTY)
+ var write = emit;
+ if (filename) {
+ var tmpPath = path.resolve(path.dirname(filename),
+ format('.%s-json-%s-%s.tmp', path.basename(filename), process.pid,
+ Date.now()));
+ var stats = fs.statSync(filename);
+ var f = fs.createWriteStream(tmpPath,
+ {encoding: 'utf8', mode: stats.mode});
+ write = f.write.bind(f);
+ }
+ if (headers && headers.length > 0) {
+ write(headers)
+ }
+ for (var i = 0; i < datasets.length; i++) {
+ var dataset = datasets[i];
+ var output = stringifyDatum(dataset[0], opts, isTTY);
+ var sep = dataset[1];
+ if (output && output.length) {
+ write(output);
+ write(sep);
+ } else if (dataset[2]) {
+ write(sep);
+ }
+ }
+ if (filename) {
+ f.end();
+ fs.renameSync(tmpPath, filename);
+ if (!opts.quiet) {
+ warn('json: updated "%s" in-place', filename);
+ }
+ }
+}
+
+
+/**
+ * Stringify the given datum according to the given output options.
+ */
+function stringifyDatum(datum, opts, isTTY) {
+ var output = null;
+ switch (opts.outputMode) {
+ case OM_INSPECT:
+ output = util.inspect(datum, false, Infinity, isTTY);
+ break;
+ case OM_JSON:
+ if (typeof (datum) !== 'undefined') {
+ output = JSON.stringify(datum, null, opts.jsonIndent);
+ }
+ break;
+ case OM_COMPACT:
+ // Dev Note: A still relatively experimental attempt at a more
+ // compact ouput somewhat a la Python's repr of a dict. I.e. try to
+ // fit elements on one line as much as reasonable.
+ if (datum === undefined) {
+ // pass
+ } else if (Array.isArray(datum)) {
+ var bits = ['[\n'];
+ datum.forEach(function (d) {
+ bits.push(' ')
+ bits.push(JSON.stringify(d, null, 0).replace(
+ /* JSSTYLED */
+ /,"(?![,:])/g, ', "'));
+ bits.push(',\n');
+ });
+ bits.push(bits.pop().slice(0, -2) + '\n') // drop last comma
+ bits.push(']');
+ output = bits.join('');
+ } else {
+ output = JSON.stringify(datum, null, 0);
+ }
+ break;
+ case OM_JSONY:
+ if (typeof (datum) === 'string') {
+ output = datum;
+ } else if (typeof (datum) !== 'undefined') {
+ output = JSON.stringify(datum, null, opts.jsonIndent);
+ }
+ break;
+ default:
+ throw new Error('unknown output mode: ' + opts.outputMode);
+ }
+ return output;
+}
+
+
+/**
+ * Print out a single result, considering input options.
+ *
+ * @deprecated
+ */
+function printDatum(datum, opts, sep, alwaysPrintSep) {
+ var output = stringifyDatum(datum, opts);
+ if (output && output.length) {
+ emit(output);
+ emit(sep);
+ } else if (alwaysPrintSep) {
+ emit(sep);
+ }
+}
+
+
+var stdoutFlushed = true;
+function emit(s) {
+ // TODO:PERF If this is try/catch is too slow (too granular): move up to
+ // mainline and be sure to only catch this particular error.
+ if (drainingStdout) {
+ return;
+ }
+ try {
+ stdoutFlushed = process.stdout.write(s);
+ } catch (e) {
+ // Handle any exceptions in stdout writing in the 'error' event above.
+ }
+}
+
+process.stdout.on('error', function (err) {
+ if (err.code === 'EPIPE') {
+ // See <https://github.com/trentm/json/issues/9>.
+ drainStdoutAndExit(0);
+ } else {
+ warn(err)
+ drainStdoutAndExit(1);
+ }
+});
+
+
+/**
+ * A hacked up version of 'process.exit' that will first drain stdout
+ * before exiting. *WARNING: This doesn't stop event processing.* IOW,
+ * callers have to be careful that code following this call isn't
+ * accidentally executed.
+ *
+ * In node v0.6 "process.stdout and process.stderr are blocking when they
+ * refer to regular files or TTY file descriptors." However, this hack might
+ * still be necessary in a shell pipeline.
+ */
+var drainingStdout = false;
+function drainStdoutAndExit(code) {
+ if (drainingStdout) {
+ return;
+ }
+ drainingStdout = true;
+ process.stdout.on('drain', function () {
+ process.exit(code);
+ });
+ process.stdout.on('close', function () {
+ process.exit(code);
+ });
+ if (stdoutFlushed) {
+ process.exit(code);
+ }
+}
+
+
+/**
+ * Return a function for the given JS code that returns.
+ *
+ * If no 'return' in the given javascript snippet, then assume we are a single
+ * statement and wrap in 'return (...)'. This is for convenience for short
+ * '-c ...' snippets.
+ */
+function funcWithReturnFromSnippet(js) {
+ // auto-"return"
+ if (js.indexOf('return') === -1) {
+ if (js.substring(js.length - 1) === ';') {
+ js = js.substring(0, js.length - 1);
+ }
+ js = 'return (' + js + ')';
+ }
+ return (new Function(js));
+}
+
+
+
+//---- mainline
+
+function main(argv) {
+ var opts;
+ try {
+ opts = parseArgv(argv);
+ } catch (e) {
+ warn('json: error: %s', e.message)
+ return drainStdoutAndExit(1);
+ }
+ //warn(opts);
+ if (opts.help) {
+ printHelp();
+ return;
+ }
+ if (opts.version) {
+ if (opts.outputMode === OM_JSON) {
+ var v = {
+ version: getVersion(),
+ author: 'Trent Mick',
+ project: 'https://github.com/trentm/json'
+ };
+ console.log(JSON.stringify(v, null, opts.jsonIndent));
+ } else {
+ console.log('json ' + getVersion());
+ console.log('written by Trent Mick');
+ console.log('https://github.com/trentm/json');
+ }
+ return;
+ }
+ var lookupStrs = opts.args;
+
+ // Prepare condition and execution funcs (and vm scripts) for -c/-e.
+ var execVm = Boolean(process.env.JSON_EXEC &&
+ process.env.JSON_EXEC === 'vm');
+ var i;
+ var condFuncs = [];
+ if (!execVm) {
+ for (i = 0; i < opts.condSnippets.length; i++) {
+ condFuncs[i] = funcWithReturnFromSnippet(opts.condSnippets[i]);
+ }
+ }
+ var condScripts = [];
+ if (execVm) {
+ for (i = 0; i < opts.condSnippets.length; i++) {
+ condScripts[i] = vm.createScript(opts.condSnippets[i]);
+ }
+ }
+ var cond = Boolean(condFuncs.length + condScripts.length);
+ var exeFuncs = [];
+ if (!execVm) {
+ for (i = 0; i < opts.exeSnippets.length; i++) {
+ exeFuncs[i] = new Function(opts.exeSnippets[i]);
+ }
+ }
+ var exeScripts = [];
+ if (execVm) {
+ for (i = 0; i < opts.exeSnippets.length; i++) {
+ exeScripts[i] = vm.createScript(opts.exeSnippets[i]);
+ }
+ }
+ var exe = Boolean(exeFuncs.length + exeScripts.length);
+
+ var lookups = lookupStrs.map(function (lookup) {
+ return parseLookup(lookup, opts.lookupDelim);
+ });
+
+ if (opts.group && opts.array && opts.outputMode !== OM_JSON) {
+ // streaming
+ var chunker = chunkEmitter(opts);
+ chunker.on('error', function (error) {
+ warn('json: error: %s', err);
+ return drainStdoutAndExit(1);
+ });
+ chunker.on('chunk', parseChunk);
+ } else if (opts.inPlace) {
+ assert.equal(opts.inputFiles.length, 1,
+ 'cannot handle more than one file with -I');
+ getInput(opts, function (err, content, filename) {
+ if (err) {
+ warn('json: error: %s', err)
+ return drainStdoutAndExit(1);
+ }
+
+ // Take off a leading HTTP header if any and pass it through.
+ var headers = [];
+ while (true) {
+ if (content.slice(0, 5) === 'HTTP/') {
+ var index = content.indexOf('\r\n\r\n');
+ var sepLen = 4;
+ if (index == -1) {
+ index = content.indexOf('\n\n');
+ sepLen = 2;
+ }
+ if (index != -1) {
+ if (!opts.dropHeaders) {
+ headers.push(content.slice(0, index + sepLen));
+ }
+ var is100Continue = (
+ content.slice(0, 21) === 'HTTP/1.1 100 Continue');
+ content = content.slice(index + sepLen);
+ if (is100Continue) {
+ continue;
+ }
+ }
+ }
+ break;
+ }
+ parseChunk(content, undefined, filename, true, headers.join(''));
+ });
+ } else {
+ // not streaming
+ getInput(opts, function (err, buffer, filename) {
+ if (err) {
+ warn('json: error: %s', err)
+ return drainStdoutAndExit(1);
+ }
+ // Take off a leading HTTP header if any and pass it through.
+ while (true) {
+ if (buffer.slice(0, 5) === 'HTTP/') {
+ var index = buffer.indexOf('\r\n\r\n');
+ var sepLen = 4;
+ if (index == -1) {
+ index = buffer.indexOf('\n\n');
+ sepLen = 2;
+ }
+ if (index != -1) {
+ if (!opts.dropHeaders) {
+ emit(buffer.slice(0, index + sepLen));
+ }
+ var is100Continue = (
+ buffer.slice(0, 21) === 'HTTP/1.1 100 Continue');
+ buffer = buffer.slice(index + sepLen);
+ if (is100Continue) {
+ continue;
+ }
+ }
+ }
+ break;
+ }
+ parseChunk(buffer, null, filename, false);
+ });
+ }
+
+ /**
+ * Parse a single chunk of JSON. This may be called more than once
+ * (when streaming or when operating on multiple files).
+ *
+ * @param chunk {String} The JSON-encoded string.
+ * @param obj {Object} Optional. For some code paths while streaming `obj`
+ * will be provided. This is an already parsed JSON object.
+ * @param filename {String} Optional. The filename from which this content
+ * came, if relevant.
+ * @param inPlace {Boolean} Optional. If true, then output will be written
+ * to `filename`.
+ * @param headers {String} Optional. Leading HTTP headers, if any to emit.
+ */
+ function parseChunk(chunk, obj, filename, inPlace, headers) {
+ // Expect the chunk to be JSON.
+ if (!chunk.length) {
+ return;
+ }
+ // parseInput() -> {datum: <input object>, error: <error object>}
+ var input = parseInput(chunk, obj, opts.group, opts.merge);
+ if (input.error) {
+ // Doesn't look like JSON. Just print it out and move on.
+ if (!opts.quiet) {
+ // Use JSON-js' "json_parse" parser to get more detail on the
+ // syntax error.
+ var details = '';
+ var normBuffer = chunk.replace(/\r\n|\n|\r/, '\n');
+ try {
+ json_parse(normBuffer);
+ details = input.error;
+ } catch (err) {
+ // err.at has the position. Get line/column from that.
+ var at = err.at - 1; // `err.at` looks to be 1-based.
+ var lines = chunk.split('\n');
+ var line, col, pos = 0;
+ for (line = 0; line < lines.length; line++) {
+ pos += lines[line].length + 1;
+ if (pos > at) {
+ col = at - (pos - lines[line].length - 1);
+ break;
+ }
+ }
+ var spaces = '';
+ for (var i = 0; i < col; i++) {
+ spaces += '.';
+ }
+ details = err.message + ' at line ' + (line + 1) +
+ ', column ' + (col + 1) + ':\n ' +
+ lines[line] + '\n ' + spaces + '^';
+ }
+ warn('json: error: %s is not JSON: %s',
+ filename ? '"' + filename + '"' : 'input', details);
+ }
+ if (!opts.validate) {
+ emit(chunk);
+ if (chunk.length && chunk[chunk.length - 1] !== '\n') {
+ emit('\n');
+ }
+ }
+ return drainStdoutAndExit(1);
+ }
+ if (opts.validate) {
+ return drainStdoutAndExit(0);
+ }
+ var data = input.datum;
+
+ // Process: items (-M, --items)
+ if (opts.items) {
+ if (!Array.isArray(data)) {
+ var key;
+ var array = [];
+ for (key in data) {
+ if (data.hasOwnProperty(key)) {
+ array.push({
+ key: key,
+ value: data[key]
+ });
+ }
+ }
+ data = array;
+ }
+ }
+
+ // Process: executions (-e, -E)
+ var i, j;
+ if (!exe) {
+ /* pass */
+ } else if (opts.array || (opts.array === null && Array.isArray(data))) {
+ var arrayified = false;
+ if (!Array.isArray(data)) {
+ arrayified = true;
+ data = [data];
+ }
+ for (i = 0; i < data.length; i++) {
+ var datum = data[i];
+ for (j = 0; j < exeFuncs.length; j++) {
+ exeFuncs[j].call(datum);
+ }
+ for (j = 0; j < exeScripts.length; j++) {
+ exeScripts[j].runInNewContext(datum);
+ }
+ }
+ if (arrayified) {
+ data = data[0];
+ }
+ } else {
+ for (j = 0; j < exeFuncs.length; j++) {
+ exeFuncs[j].call(data);
+ }
+ for (j = 0; j < exeScripts.length; j++) {
+ exeScripts[j].runInNewContext(data);
+ }
+ }
+
+ // Process: conditionals (-c)
+ if (!cond) {
+ /* pass */
+ } else if (opts.array || (opts.array === null && Array.isArray(data))) {
+ var arrayified = false;
+ if (!Array.isArray(data)) {
+ arrayified = true;
+ data = [data];
+ }
+ var filtered = [];
+ for (i = 0; i < data.length; i++) {
+ var datum = data[i];
+ var datumCopy = objCopy(datum);
+ var keep = true;
+ // TODO(perf): Perhaps drop the 'datumCopy'? "this is a gun"
+ for (j = 0; j < condFuncs.length; j++) {
+ if (!condFuncs[j].call(datumCopy)) {
+ keep = false;
+ break;
+ }
+ }
+ if (keep) {
+ for (j = 0; j < condScripts.length; j++) {
+ if (!condScripts[j].runInNewContext(datumCopy)) {
+ keep = false;
+ break;
+ }
+ }
+ if (keep) {
+ filtered.push(datum);
+ }
+ }
+ }
+ if (arrayified) {
+ data = (filtered.length ? filtered[0] : []);
+ } else {
+ data = filtered;
+ }
+ } else {
+ var keep = true;
+ var dataCopy = objCopy(data);
+ for (j = 0; j < condFuncs.length; j++) {
+ // TODO(perf): Perhaps drop the 'dataCopy'? "this is a gun"
+ if (!condFuncs[j].call(dataCopy)) {
+ keep = false;
+ break;
+ }
+ }
+ if (keep) {
+ for (j = 0; j < condScripts.length; j++) {
+ if (!condScripts[j].runInNewContext(dataCopy)) {
+ keep = false;
+ break;
+ }
+ }
+ }
+ if (!keep) {
+ data = undefined;
+ }
+ }
+
+ // Process: lookups
+ var lookupsAreIndeces = false;
+ if (lookups.length) {
+ if (opts.array) {
+ if (!Array.isArray(data)) data = [data];
+ var table = [];
+ for (j = 0; j < data.length; j++) {
+ var datum = data[j];
+ var row = {};
+ for (i = 0; i < lookups.length; i++) {
+ var lookup = lookups[i];
+ var value = lookupDatum(datum, lookup);
+ if (value !== undefined) {
+ row[lookup.join('.')] = value;
+ }
+ }
+ table.push(row);
+ }
+ data = table;
+ } else {
+ // Special case handling: Note if the 'lookups' are indeces into
+ // an array. This may be used below to change the output
+ // representation.
+ if (Array.isArray(data)) {
+ lookupsAreIndeces = true;
+ for (i = 0; i < lookups.length; i++) {
+ if (lookups[i].length !== 1 ||
+ isNaN(Number(lookups[i])))
+ {
+ lookupsAreIndeces = false;
+ break;
+ }
+ }
+ }
+ var row = {};
+ for (i = 0; i < lookups.length; i++) {
+ var lookup = lookups[i];
+ var value = lookupDatum(data, lookup);
+ if (value !== undefined) {
+ row[lookup.join('.')] = value;
+ }
+ }
+ data = row;
+ }
+ }
+
+ // --keys
+ if (opts.outputKeys) {
+ var data = Object.keys(data);
+ }
+
+ // Output
+ var datasets = [];
+ if (opts.outputMode === OM_JSON) {
+ if (lookups.length === 1 && !opts.array) {
+ /**
+ * Special case: For JSON output of a *single* lookup, *don't*
+ * use the full table structure, else there is no way to get
+ * string quoting for a single value:
+ * $ echo '{"a": [], "b": "[]"}' | json -j a
+ * []
+ * $ echo '{"a": [], "b": "[]"}' | json -j b
+ * '[]'
+ * See <https://github.com/trentm/json/issues/35> for why.
+ */
+ data = data[lookups[0].join('.')];
+ } else if (lookupsAreIndeces) {
+ /**
+ * Special case: Lookups that are all indeces into an input
+ * array are more likely to be wanted as an array of selected
+ * items rather than a 'JSON table' thing that we use otherwise.
+ */
+ var flattened = [];
+ for (i = 0; i < lookups.length; i++) {
+ var lookupStr = lookups[i].join('.');
+ if (data.hasOwnProperty(lookupStr)) {
+ flattened.push(data[lookupStr])
+ }
+ }
+ data = flattened;
+ }
+ // If JSON output mode, then always just output full set of data to
+ // ensure valid JSON output.
+ datasets.push([data, '\n', false]);
+ } else if (lookups.length) {
+ if (opts.array) {
+ // Output `data` as a 'table' of lookup results.
+ for (j = 0; j < data.length; j++) {
+ var row = data[j];
+ for (i = 0; i < lookups.length - 1; i++) {
+ datasets.push([row[lookups[i].join('.')],
+ opts.delim, true]);
+ }
+ datasets.push([row[lookups[i].join('.')], '\n', true]);
+ }
+ } else {
+ for (i = 0; i < lookups.length; i++) {
+ datasets.push([data[lookups[i].join('.')], '\n', false]);
+ }
+ }
+ } else if (opts.array) {
+ if (!Array.isArray(data)) data = [data];
+ for (j = 0; j < data.length; j++) {
+ datasets.push([data[j], '\n', false]);
+ }
+ } else {
+ // Output `data` as is.
+ datasets.push([data, '\n', false]);
+ }
+ printDatasets(datasets, inPlace ? filename : undefined, headers, opts);
+ }
+}
+
+if (require.main === module) {
+ // HACK guard for <https://github.com/trentm/json/issues/24>.
+ // We override the `process.stdout.end` guard that core node.js puts in
+ // place. The real fix is that `.end()` shouldn't be called on stdout
+ // in node core. Hopefully node v0.6.9 will fix that. Only guard
+ // for v0.6.0..v0.6.8.
+ var nodeVer = process.versions.node.split('.').map(Number);
+ if ([0, 6, 0] <= nodeVer && nodeVer <= [0, 6, 8]) {
+ var stdout = process.stdout;
+ stdout.end = stdout.destroy = stdout.destroySoon = function () {
+ /* pass */
+ };
+ }
+
+ main(process.argv);
+}
--- /dev/null
+<?php
+
+ require_once('protected/required.php');
+
+ interface ExploitantManager {
+
+ function createExploitant($exploitant);
+ function updateExploitant($exploitant);
+ function getExploitant($id);
+ function getExploitants();
+ function getExploitantByReference($reference);
+ function removeExploitant($exploitant);
+ }
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+ require_once('protected/required.php');
+
+ class PdoExploitantManager extends AbstractPdoManager implements ExploitantManager {
+
+ public function createExploitant($exploitant) {
+
+ $query = $this -> pdo -> prepare(
+ 'INSERT INTO exploitants (nom, reference, produits) VALUES (:nom, :reference, :produits)'
+ );
+ $query -> bindValue(':nom', $exploitant -> getNom());
+ $query -> bindValue(':reference', $exploitant -> getReference());
+ $query -> bindValue(':produits', implode($exploitant -> getProduits()));
+ $query -> execute();
+ $query -> closeCursor();
+
+ }
+
+ public function updateExploitant($exploitant) {
+
+ $query = $this -> pdo -> prepare(
+ 'UPDATE exploitants SET nom = :nom, reference = :reference, produits = :produits WHERE id = :id'
+ );
+ $query -> bindValue(':id', $exploitant -> getId());
+ $query -> bindValue(':nom', $exploitant -> getNom());
+ $query -> bindValue(':reference', $exploitant -> getReference());
+ $query -> bindValue(':produits', implode("|", $exploitant -> getProduits()));
+ $query -> execute();
+
+ }
+
+ public function getExploitant($id) {
+
+ $query = $this -> pdo -> prepare('SELECT * FROM exploitants WHERE id = :id');
+ $query -> bindValue(':id', $id);
+ $query -> execute();
+
+ $result = $query -> fetch(PDO::FETCH_ASSOC);
+ $exploitant = new Exploitant($result['id'], $result['nom'], $result['reference'], explode("|", $result['produits']));
+
+ $query->closeCursor();
+
+ return $exploitant;
+ }
+
+ public function getExploitants() {
+
+ $query = $this -> pdo -> prepare('SELECT * FROM exploitants');
+ $query -> execute();
+
+ $results = $query -> fetchAll(PDO::FETCH_ASSOC);
+ $exploitants = array();
+ foreach ($results as $result) {
+ $exploitants[] = new Exploitant($result['id'], $result['nom'], $result['reference'], explode("|", $result['produits']));
+ }
+
+ $query->closeCursor();
+
+ return $exploitants;
+ }
+
+ public function getExploitantByReference($reference) {
+
+ $query = $this -> pdo -> prepare('SELECT * FROM exploitants WHERE reference = :reference');
+ $query -> bindValue(':reference', $reference);
+ $query -> execute();
+
+ $result = $query -> fetch(PDO::FETCH_ASSOC);
+ $exploitant = new Exploitant($result['id'], $result['nom'], $result['reference'], explode("|", $result['produits']));
+
+ $query->closeCursor();
+
+ return $exploitant;
+ }
+
+ public function removeExploitant($exploitant) {
+
+ $query = $this -> pdo -> prepare('DELETE FROM exploitant WHERE id = :id');
+ $query -> bindValue('id', $exploitant -> getId());
+ $query -> execute();
+
+ }
+
+ }
+
+?>
public function createProduit($produit) {\r
\r
$query = $this -> pdo -> prepare(\r
- 'INSERT INTO produits (nom, reference, version) VALUES (:nom, :reference, :version)'\r
+ 'INSERT INTO produits (nom, exploitant, reference, version) VALUES (:nom, :exploitant, :reference, :version)'\r
);\r
$query -> bindValue(':nom', $produit -> getNom());\r
+ $query -> bindValue(':exploitant', $produit -> getExploitant());\r
$query -> bindValue(':reference', $produit -> getReference());\r
$query -> bindValue(':version', $produit -> getVersion());\r
$query -> execute();\r
public function updateProduit($produit) {\r
\r
$query = $this -> pdo -> prepare(\r
- 'UPDATE produits SET nom = :nom, reference = :reference, version = :version WHERE id = :id'\r
+ 'UPDATE produits SET nom = :nom, exploitant = :exploitant, reference = :reference, version = :version WHERE id = :id'\r
);\r
$query -> bindValue(':id', $produit -> getId());\r
$query -> bindValue(':nom', $produit -> getNom());\r
+ $query -> bindValue(':exploitant', $produit -> getExploitant());\r
$query -> bindValue(':reference', $produit -> getReference());\r
$query -> bindValue(':version', $produit -> getVersion());\r
$query -> execute();\r
\r
public function updateProduitInfos($array) {\r
\r
- /// TO-DO : Check refClient\r
-\r
$produit = $this -> getProduitByReference($array['reference']);\r
\r
if ($array['produit'] == $produit -> getNom()) {\r
- /// TO-DO : Test de version (si pas supporté = erreur)\r
$query = $this -> pdo -> prepare(\r
'UPDATE produits SET version = :version WHERE reference = :reference'\r
);\r
$query -> bindValue(':reference', $array['reference']);\r
$query -> bindValue(':version', $array['version']);\r
$query -> execute();\r
+ \r
+ // CAS EXPLOITANT\r
+ if($array['usager_type'] == "exploitant") {\r
+ // RECUPERATION DE L'EXPLOITANT DU PRODUIT\r
+ $exploitantManager = new PdoExploitantManager();\r
+ $exploitant = $exploitantManager -> getExploitant($produit -> getExploitant());\r
+\r
+ // MISE À JOUR DE TOUS LES PRODUITS EN CHARGE DE L'EXPLOITANT\r
+ $produits_refs = $exploitant -> getProduits();\r
+ $array['usager_type'] = 'client';\r
+ foreach ($produits_refs as $produit_ref) {\r
+ $array['reference'] = $produit_ref;\r
+ $produitManager -> updateProduitInfos($array);\r
+ }\r
+ }\r
+\r
}\r
else {\r
echo "Erreur : le nom du produit a changé";\r
$query -> execute();\r
\r
$result = $query -> fetch(PDO::FETCH_ASSOC);\r
- $produit = new Produit($result['id'], $result['nom'], $result['reference'], $result['version']);\r
+ $produit = new Produit($result['id'], $result['nom'], $result['exploitant'], $result['reference'], $result['version']);\r
\r
$query->closeCursor();\r
\r
$query -> execute();\r
\r
$result = $query -> fetch(PDO::FETCH_ASSOC);\r
- $produit = new Produit($result['id'], $result['nom'], $result['reference'], $result['version']);\r
+ $produit = new Produit($result['id'], $result['nom'], $result['exploitant'], $result['reference'], $result['version']);\r
\r
$query->closeCursor();\r
\r
$results = $query -> fetchAll(PDO::FETCH_ASSOC);\r
$version = array();\r
foreach ($results as $result) {\r
- $version[] = new Produit($result['id'], $result['nom'], $result['reference'], $result['version']);\r
+ $version[] = new Produit($result['id'], $result['nom'], $result['exploitant'], $result['reference'], $result['version']);\r
}\r
\r
$query->closeCursor();\r
--- /dev/null
+<?php\r
+\r
+ require_once('protected/required.php');\r
+\r
+ class Exploitant {\r
+\r
+ protected $id, $nom, $reference, $produits;\r
+ \r
+ /// CONSTRUCTEUR\r
+ function __construct($id = null, $nom = null, $reference = null, $produits = null) {\r
+\r
+ $this -> id = $id;\r
+ $this -> nom = $nom;\r
+ $this -> reference = $reference;\r
+ $this -> produits = $produits;\r
+\r
+ }\r
+\r
+ public function getJSON() {\r
+ return json_encode(get_object_vars($this));\r
+ }\r
+ \r
+ public function getJSONP() {\r
+ $array["id"] = $this -> id;\r
+ $array["nom"] = $this -> nom;\r
+ $array["reference"] = $this -> reference;\r
+ $array["produits"] = $this -> produits;\r
+\r
+ return json_encode($array);\r
+ }\r
+\r
+ /// GETTERS\r
+ public function getId() { return $this -> id; }\r
+ public function getNom() { return $this->nom; }\r
+ public function getReference() { return $this->reference; }\r
+ public function getProduits() { return $this->produits; }\r
+ \r
+ /// SETTERS\r
+ public function setId($id) { $this -> id = $id; }\r
+ public function setNom($nom) { $this->nom = $nom; }\r
+ public function setReference($reference) { $this->reference = $reference; }\r
+ public function setProduits($produits) { $this->produits = $produits; }\r
+\r
+ }\r
+\r
+?>
\ No newline at end of file
\r
class Produit {\r
\r
- protected $id, $nom, $reference, $version;\r
+ protected $id, $nom, $exploitant, $reference, $version;\r
\r
/// CONSTRUCTEUR\r
- function __construct($id = null, $nom = null, $reference = null, $version = null) {\r
+ function __construct($id = null, $nom = null, $exploitant = null, $reference = null, $version = null) {\r
\r
$this -> id = $id;\r
$this -> nom = $nom;\r
+ $this -> exploitant = $exploitant;\r
$this -> reference = $reference;\r
$this -> version = $version;\r
\r
+ // TO-DO : AJOUT DE :\r
+ /*\r
+ - fqdnInterne\r
+ - fqdnExterne\r
+ - systeme\r
+ - uid\r
+ - historique\r
+ */\r
}\r
\r
public function getJSON() {\r
public function getJSONP() {\r
$array["id"] = $this -> id;\r
$array["nom"] = $this -> nom;\r
+ $array["exploitant"] = $this -> exploitant;\r
$array["reference"] = $this -> reference;\r
$array["version"] = $this -> version;\r
\r
/// GETTERS\r
public function getId() { return $this -> id; }\r
public function getNom() { return $this->nom; }\r
+ public function getExploitant() { return $this->exploitant; }\r
public function getReference() { return $this->reference; }\r
public function getVersion() { return $this->version; }\r
\r
/// SETTERS\r
public function setId($id) { $this -> id = $id; }\r
public function setNom($nom) { $this->nom = $nom; }\r
+ public function setExploitant($exploitant) { $this->exploitant = $exploitant; }\r
public function setReference($reference) { $this->reference = $reference; }\r
public function setVersion($version) { $this->version = $version; }\r
\r
<?php\r
\r
function api_delete() {\r
- $usagerManager = new PdoUsagerManager();\r
+ $exploitantManager = new PdoExploitantManager();\r
$produitManager = new PdoProduitManager();\r
\r
switch ($_GET['method']) {\r
- case 'remove_usager' :\r
- $usager = new Usager($_GET['usager']['id'], $_GET['usager']['nom'], $_GET['usager']['reference'], $_GET['usager']['produits']);\r
- $usagerManager -> removeUsager($usager);\r
+ case 'remove_exploitant' :\r
+ $exploitant = new Exploitant($_GET['exploitant']['id'], $_GET['exploitant']['nom'], $_GET['exploitant']['reference'], $_GET['exploitant']['produits']);\r
+ $exploitantManager -> removeExploitant($exploitant);\r
break;\r
case 'remove_produit' :\r
$produit = new Produit($_GET['produit']['id'], $_GET['produit']['fqdn'], $_GET['produit']['nom'], $_GET['produit']['version']);\r
<?php\r
\r
function api_get() {\r
- $usagerManager = new PdoUsagerManager();\r
+ $exploitantManager = new PdoExploitantManager();\r
$produitManager = new PdoProduitManager();\r
\r
switch ($_GET['action']) {\r
- case 'get_usager' :\r
- echo $usagerManager -> getUsager($_GET['id']) -> getJSONP();\r
+ case 'get_exploitant' :\r
+ echo $exploitantManager -> getExploitant($_GET['id']) -> getJSONP();\r
break;\r
\r
- case 'get_usagers' :\r
- $usagers = $usagerManager -> getUsagers();\r
- if (!empty($usagers)) {\r
+ case 'get_exploitants' :\r
+ $exploitants = $exploitantManager -> getExploitants();\r
+ if (!empty($exploitants)) {\r
$i = 0;\r
echo '[';\r
- foreach ($usagers as $usager) {\r
- echo $usager -> getJSON();\r
- if ($i != sizeof($usagers) - 1) {\r
+ foreach ($exploitants as $exploitant) {\r
+ echo $exploitant -> getJSON();\r
+ if ($i != sizeof($exploitants) - 1) {\r
echo ',';\r
}\r
$i++;\r
<?php\r
\r
function api_post() {\r
- $usagerManager = new PdoUsagerManager();\r
+ $exploitantManager = new PdoExploitantManager();\r
$produitManager = new PdoProduitManager();\r
\r
switch ($_GET['action']) {\r
- case 'create_usager' :\r
- $usager = new Usager($_POST['nom'], $_POST['reference'], $_POST['produits']);\r
- $usagerManager -> createUsager($usager);\r
+ case 'create_exploitant' :\r
+ $exploitant = new Exploitant(null, $_POST['nom'], $_POST['reference'], $_POST['produits']);\r
+ $exploitantManager -> createExploitant($exploitant);\r
break;\r
\r
- case 'update_usager' :\r
- $usager = new Usager($_POST['nom'], $_POST['reference'], $_POST['produits']);\r
- $usagerManager -> updateUsager($usager);\r
+ case 'update_exploitant' :\r
+ $exploitant = new Exploitant($_POST['id'], $_POST['nom'], $_POST['reference'], $_POST['produits']);\r
+ $exploitantManager -> updateExploitant($exploitant);\r
break;\r
\r
case 'add_produit' :\r
if ($_GET['action'] == 'upload_info') {\r
// DECODE JSON\r
$array = json_decode($data, true);\r
- var_dump($array);\r
- \r
+ //var_dump($array);\r
+\r
if (!is_null($array) && assert($array)) {\r
// MISE A JOUR PRODUIT\r
$produitManager -> updateProduitInfos($array);\r
\r
header('Content-Type: text/html; charset=utf-8');\r
\r
- require_once('classes/models/Usager.class.php');\r
+ require_once('classes/models/Exploitant.class.php');\r
require_once('classes/models/Produit.class.php');\r
\r
- require_once('classes/manager/UsagerManager.class.php');\r
+ require_once('classes/manager/ExploitantManager.class.php');\r
require_once('classes/manager/ProduitManager.class.php');\r
\r
require_once('classes/manager/pdo/AbstractPdoManager.php');\r
- require_once('classes/manager/pdo/PdoUsagerManager.php');\r
+ require_once('classes/manager/pdo/PdoExploitantManager.php');\r
require_once('classes/manager/pdo/PdoProduitManager.php');\r
\r
?>
\ No newline at end of file
<nodes id="2">
<ClassNode id="3">
<children id="4"/>
- <location class="Point2D.Double" id="5" x="60.0" y="50.0"/>
- <id id="6" value="589cc270-198f-41bf-9193-a6d5c1d0055d"/>
+ <location class="Point2D.Double" id="5" x="280.0" y="40.0"/>
+ <id id="6" value="eb36e84d-0e71-4c46-a90f-963cb632a0b9"/>
<revision>1</revision>
<backgroundColor id="7">
<red>255</red>
</borderColor>
<textColor reference="8"/>
<name id="9" justification="1" size="3" underlined="false">
- <text>Client</text>
- </name>
- <attributes id="10" justification="0" size="4" underlined="false">
- <text></text>
- </attributes>
- <methods id="11" justification="0" size="4" underlined="false">
- <text></text>
- </methods>
- </ClassNode>
- <ClassNode id="12">
- <children id="13"/>
- <location class="Point2D.Double" id="14" x="380.0" y="120.0"/>
- <id id="15" value="eb36e84d-0e71-4c46-a90f-963cb632a0b9"/>
- <revision>1</revision>
- <backgroundColor reference="7"/>
- <borderColor reference="8"/>
- <textColor reference="8"/>
- <name id="16" justification="1" size="3" underlined="false">
<text>Produit</text>
</name>
- <attributes id="17" justification="0" size="4" underlined="false">
+ <attributes id="10" justification="0" size="4" underlined="false">
<text>- nom
-- referenceProduit
+- reference
- exploitant
-- clients
- version
-- historique
- fqdnInterne
- fqdnExterne
- systeme
-- uid</text>
+- uid
+- historique</text>
</attributes>
- <methods id="18" justification="0" size="4" underlined="false">
+ <methods id="11" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
- <ClassNode id="19">
- <children id="20"/>
- <location class="Point2D.Double" id="21" x="670.0" y="170.0"/>
- <id id="22" value="70b2457f-c542-45b5-a714-a3f555cb3f7c"/>
+ <ClassNode id="12">
+ <children id="13"/>
+ <location class="Point2D.Double" id="14" x="500.0" y="80.0"/>
+ <id id="15" value="70b2457f-c542-45b5-a714-a3f555cb3f7c"/>
<revision>1</revision>
- <backgroundColor id="23">
+ <backgroundColor id="16">
<red>255</red>
<green>255</green>
<blue>255</blue>
<alpha>255</alpha>
</backgroundColor>
- <borderColor id="24">
+ <borderColor id="17">
<red>0</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</borderColor>
- <textColor reference="24"/>
- <name id="25" justification="1" size="3" underlined="false">
+ <textColor reference="17"/>
+ <name id="18" justification="1" size="3" underlined="false">
<text>Historique</text>
</name>
- <attributes id="26" justification="0" size="4" underlined="false">
+ <attributes id="19" justification="0" size="4" underlined="false">
<text>- installation
- misesAJour
- patchs</text>
</attributes>
- <methods id="27" justification="0" size="4" underlined="false">
+ <methods id="20" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
- <ClassNode id="28">
- <children id="29"/>
- <location class="Point2D.Double" id="30" x="60.0" y="330.0"/>
- <id id="31" value="ee381e24-ebf6-4e54-b1b6-267a5a093fe9"/>
+ <ClassNode id="21">
+ <children id="22"/>
+ <location class="Point2D.Double" id="23" x="50.0" y="80.0"/>
+ <id id="24" value="ee381e24-ebf6-4e54-b1b6-267a5a093fe9"/>
<revision>1</revision>
- <backgroundColor reference="23"/>
- <borderColor reference="24"/>
- <textColor reference="24"/>
- <name id="32" justification="1" size="3" underlined="false">
+ <backgroundColor reference="16"/>
+ <borderColor reference="17"/>
+ <textColor reference="17"/>
+ <name id="25" justification="1" size="3" underlined="false">
<text>Exploitant</text>
</name>
- <attributes id="33" justification="0" size="4" underlined="false">
- <text></text>
- </attributes>
- <methods id="34" justification="0" size="4" underlined="false">
- <text></text>
- </methods>
- </ClassNode>
- <ClassNode id="35">
- <children id="36"/>
- <location class="Point2D.Double" id="37" x="60.0" y="170.0"/>
- <id id="38" value="07844142-289f-493e-8e07-2428f29b5c5c"/>
- <revision>1</revision>
- <backgroundColor id="39">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- <alpha>255</alpha>
- </backgroundColor>
- <borderColor id="40">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- <alpha>255</alpha>
- </borderColor>
- <textColor reference="40"/>
- <name id="41" justification="1" size="3" underlined="false">
- <text>Usager</text>
- </name>
- <attributes id="42" justification="0" size="4" underlined="false">
+ <attributes id="26" justification="0" size="4" underlined="false">
<text>- nom
-- reference</text>
+- reference
+- produits</text>
</attributes>
- <methods id="43" justification="0" size="4" underlined="false">
+ <methods id="27" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
</nodes>
- <edges id="44">
- <AggregationEdge id="45">
- <start class="ClassNode" reference="12"/>
- <end class="ClassNode" reference="19"/>
- <startLocation class="Point2D.Double" id="46" x="80.0" y="70.0"/>
- <endLocation class="Point2D.Double" id="47" x="20.0" y="40.0"/>
- <transitionPoints id="48"/>
- <id id="49" value="8c07c7e3-f62b-4c27-bd0a-ef2d27363ad7"/>
+ <edges id="28">
+ <AggregationEdge id="29">
+ <start class="ClassNode" reference="3"/>
+ <end class="ClassNode" reference="12"/>
+ <startLocation class="Point2D.Double" id="30" x="80.0" y="70.0"/>
+ <endLocation class="Point2D.Double" id="31" x="20.0" y="40.0"/>
+ <transitionPoints id="32"/>
+ <id id="33" value="8c07c7e3-f62b-4c27-bd0a-ef2d27363ad7"/>
<revision>1</revision>
- <bentStyle id="50" name="AUTO"/>
+ <bentStyle id="34" name="AUTO"/>
<startLabel>1</startLabel>
<middleLabel></middleLabel>
<endLabel>1</endLabel>
</AggregationEdge>
- <CompositionEdge id="51">
- <start class="ClassNode" reference="12"/>
- <end class="ClassNode" reference="28"/>
- <startLocation class="Point2D.Double" id="52" x="40.0" y="150.0"/>
- <endLocation class="Point2D.Double" id="53" x="120.0" y="40.0"/>
- <transitionPoints id="54">
- <Point2D.Double id="55" x="450.0" y="360.0"/>
- </transitionPoints>
- <id id="56" value="17eb0b64-bc21-4b57-929c-1e725e0d2ffb"/>
- <revision>1</revision>
- <bentStyle id="57" name="FREE"/>
- <startLabel>0,*</startLabel>
- <middleLabel></middleLabel>
- <endLabel>0,1</endLabel>
- </CompositionEdge>
- <CompositionEdge id="58">
- <start class="ClassNode" reference="12"/>
+ <AggregationEdge id="35">
+ <start class="ClassNode" reference="21"/>
<end class="ClassNode" reference="3"/>
- <startLocation class="Point2D.Double" id="59" x="60.0" y="60.0"/>
- <endLocation class="Point2D.Double" id="60" x="80.0" y="70.0"/>
- <transitionPoints id="61">
- <Point2D.Double id="62" x="450.0" y="80.0"/>
- </transitionPoints>
- <id id="63" value="eef11a22-7824-4336-be1e-e31794be3ab8"/>
+ <startLocation class="Point2D.Double" id="36" x="80.0" y="40.0"/>
+ <endLocation class="Point2D.Double" id="37" x="20.0" y="100.0"/>
+ <transitionPoints id="38"/>
+ <id id="39" value="c5d2601e-339d-444b-893b-de5207d0ef6f"/>
<revision>1</revision>
- <bentStyle reference="57"/>
- <startLabel>1,*</startLabel>
+ <bentStyle reference="34"/>
+ <startLabel>0,1</startLabel>
<middleLabel></middleLabel>
- <endLabel>0,*</endLabel>
- </CompositionEdge>
- <InheritanceEdge id="64">
- <start class="ClassNode" reference="28"/>
- <end class="ClassNode" reference="35"/>
- <startLocation class="Point2D.Double" id="65" x="50.0" y="20.0"/>
- <endLocation class="Point2D.Double" id="66" x="50.0" y="60.0"/>
- <transitionPoints id="67"/>
- <id id="68" value="b1fbbd5c-a791-4128-b449-1c5760a29e67"/>
- <revision>1</revision>
- <bentStyle reference="50"/>
- <startLabel></startLabel>
- <middleLabel></middleLabel>
- <endLabel></endLabel>
- </InheritanceEdge>
- <InheritanceEdge id="69">
- <start class="ClassNode" reference="3"/>
- <end class="ClassNode" reference="35"/>
- <startLocation class="Point2D.Double" id="70" x="60.0" y="40.0"/>
- <endLocation class="Point2D.Double" id="71" x="50.0" y="10.0"/>
- <transitionPoints id="72"/>
- <id id="73" value="1c3cff1b-8b9e-4caa-b5aa-08867714bdba"/>
- <revision>1</revision>
- <bentStyle reference="50"/>
- <startLabel></startLabel>
- <middleLabel></middleLabel>
- <endLabel></endLabel>
- </InheritanceEdge>
+ <endLabel>1,*</endLabel>
+ </AggregationEdge>
</edges>
</ClassDiagramGraph>]]></SCRIPT>\r
<BR />\r
<BR />\r
<IMG alt="embedded diagram image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a\r
HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy\r
-MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAFZAssDASIA\r
+MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAC5AisDASIA\r
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA\r
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3\r
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm\r
AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx\r
BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK\r
U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3\r
-uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0PwX4\r
-L8K3XgXw9cXHhrRpp5dMtnkkksImZ2MSkkkrkknnNbn/AAgng/8A6FTQ/wDwXQ//ABNHgT/knnhr\r
-/sFWv/opa6CgDn/+EE8H/wDQqaH/AOC6H/4mj/hBPB//AEKmh/8Aguh/+JroKKAOf/4QTwf/ANCp\r
-of8A4Lof/iaP+EE8H/8AQqaH/wCC6H/4mugooA5//hBPB/8A0Kmh/wDguh/+Jo/4QTwf/wBCpof/\r
-AILof/ia6CigDn/+EE8H/wDQqaH/AOC6H/4mj/hBPB//AEKmh/8Aguh/+JroKKAOf/4QTwf/ANCp\r
-of8A4Lof/iaP+EE8H/8AQqaH/wCC6H/4mugooA4eXTNH8M+PdKk0nR7Gz8/TL1ZBaQJDvxLa4ztH\r
-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\r
-oUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABR\r
-RRQAUUUUAFFFFAHP+Mv+QHbf9hXTf/S2Gugrn/GX/IDtv+wrpv8A6Ww10FABRRRQAUUUUAFFFFAB\r
-RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF\r
-FFABRRRQAUUUUAc/4E/5J54a/wCwVa/+ilroK4fTJfFfhnw9pWkyaPos/wBktI7YSrq0q7/LRV3Y\r
-+zcZxnGTU/8Awkvif/oX9I/8HEv/AMjUAdjRXHf8JL4n/wChf0j/AMHEv/yNR/wkvif/AKF/SP8A\r
-wcS//I1AHY0Vx3/CS+J/+hf0j/wcS/8AyNR/wkvif/oX9I/8HEv/AMjUAdjRXCWvjTxFeXN9BH4d\r
-0sNZziCQtq8mCxjSTj/RumJB+Oatf8JL4n/6F/SP/BxL/wDI1AHY0Vx3/CS+J/8AoX9I/wDBxL/8\r
-jUf8JL4n/wChf0j/AMHEv/yNQB2NFcd/wkvif/oX9I/8HEv/AMjUf8JL4n/6F/SP/BxL/wDI1AB4\r
-l/5HfQ/+wbff+jLWuxrgJJNZ1XxFZ6hqFjYWcNraXEAW3vXnZ2keFu8SYAER9etd/QAUUUUAFFFF\r
-ABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUA\r
-FFFFAHP+Mv8AkB23/YV03/0thrUj1bTZtUm0uLULR9QhTfLaLMplReOWTOQPmXkjuPWsvxl/yA7b\r
-/sK6b/6Ww1n6jrujwfE7SLOXVbGO6XT7uBoXuEDiSSS0MaFc53MASB1OOKAOwqOCeG6t4ri3ljmg\r
-lQPHJGwZXUjIII4II5zWfeC31201HTYLnbJBKsE7BDmJ9qSDbnHzbXUhhnBIPJBFU/BXh+bwx4Vs\r
-dLuJ0nnhijWSRAeWCKpGTywBGFOB8oUY4oA6CiiigAooooAKKKKACiiigAooooAKKKKACiiigAoo\r
-ooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii\r
-gDn/AA9/yHPFn/YVj/8ASK1roK5/w9/yHPFn/YVj/wDSK1roKACiiigAooooAKKKKACiiigAoooo\r
-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\r
+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\r
-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\r
-FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAc/wCHv+Q54s/7Csf/AKRWtdBXP+Hv\r
-+Q54s/7Csf8A6RWtdBQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFF\r
-FABRRRQAUUUUAFFFFABRRRQAUUUUAc/4E/5J54a/7BVr/wCilrT1PSbLWLVbe9iZ0RxIjJI0bo46\r
-MrqQynk8gjqa5DwXoWozeBfD0qeLNZgR9MtmWKOKzKoDEvyjdATgdOST6k1uf8I9qn/Q565/35sv\r
-/kegCxY+FtG01o2tbRlZLs3oZppHJnMRhLksxJJQkHPXOevNR2/g/QrXVINRhs3W5t5Hlg/0iQpC\r
-zqytsQttUEO2QAAevUCo/wDhHtU/6HPXP+/Nl/8AI9H/AAj2qf8AQ565/wB+bL/5HoA6Ciuf/wCE\r
-e1T/AKHPXP8AvzZf/I9H/CPap/0Oeuf9+bL/AOR6AOgorn/+Ee1T/oc9c/782X/yPR/wj2qf9Dnr\r
-n/fmy/8AkegDoKK5/wD4R7VP+hz1z/vzZf8AyPR/wj2qf9Dnrn/fmy/+R6AOgorn/wDhHtU/6HPX\r
-P+/Nl/8AI9H/AAj2qf8AQ565/wB+bL/5HoA6Ciuf/wCEe1T/AKHPXP8AvzZf/I9H/CPap/0Oeuf9\r
-+bL/AOR6AOgorn/+Ee1T/oc9c/782X/yPR/wj2qf9Dnrn/fmy/8AkegDoK47xL/yO+h/9g2+/wDR\r
-lrWj/wAI9qn/AEOeuf8Afmy/+R657UtOurDxvpH2nWb7Ut+m3u37WkC+XiS1zjyo065756DGOcgH\r
-oNFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA\r
-UUUUAFFFFABRRRQAUUUUAFFFFAHP+Hv+Q54s/wCwrH/6RWtdBXP+Hv8AkOeLP+wrH/6RWtdBQAUU\r
-UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRR\r
-QAUUUUAc/wCBP+SeeGv+wVa/+ilroK4Twt4q0/R/BuhWF/a61BdW2nwQyo2i3h2usahhkRYOCO1a\r
-3/CeaH/d1f8A8El5/wDGqAOlormv+E80P+7q/wD4JLz/AONUf8J5of8Ad1f/AMEl5/8AGqAOlorm\r
-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\r
-ZaX/AM+uuf8Agivf/jNdBRQBz/8AwmWl/wDPrrn/AIIr3/4zR/wmWl/8+uuf+CK9/wDjNdBRQBz/\r
-APwmWl/8+uuf+CK9/wDjNH/CZaX/AM+uuf8Agivf/jNdBRQBz/8AwmWl/wDPrrn/AIIr3/4zR/wm\r
-Wl/8+uuf+CK9/wDjNdBRQBz/APwmWl/8+uuf+CK9/wDjNH/CZaX/AM+uuf8Agivf/jNdBRQBz/8A\r
-wmWl/wDPrrn/AIIr3/4zR/wmWl/8+uuf+CK9/wDjNdBRQBz/APwmWl/8+uuf+CK9/wDjNH/CZaX/\r
-AM+uuf8Agivf/jNdBRQBz/8AwmWl/wDPrrn/AIIr3/4zR/wmWl/8+uuf+CK9/wDjNdBRQBz/APwm\r
-Wl/8+uuf+CK9/wDjNH/CZaX/AM+uuf8Agivf/jNdBRQBz/8AwmWl/wDPrrn/AIIr3/4zR/wmWl/8\r
-+uuf+CK9/wDjNdBRQBz/APwmWl/8+uuf+CK9/wDjNH/CZaX/AM+uuf8Agivf/jNdBRQBz/8AwmWl\r
-/wDPrrn/AIIr3/4zR/wmWl/8+uuf+CK9/wDjNdBRQBxeva9bazZ2llZWWstO2p2D/vNHu4lCpdRO\r
-xLPGFACqTkkdK7SiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKK\r
-ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOf8Cf8AJPPDX/YKtf8A0UtdBXP+\r
-BP8Aknnhr/sFWv8A6KWugoAKKKKACiiigAooooAKKKKACiiigDjvEv8AyO+h/wDYNvv/AEZa12Nc\r
-d4l/5HfQ/wDsG33/AKMta7GgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo\r
-oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig\r
-AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAO\r
-H0yXxX4Z8PaVpMmj6LP9ktI7YSrq0q7/AC0Vd2Ps3GcZxk1P/wAJL4n/AOhf0j/wcS//ACNXY0UA\r
-cd/wkvif/oX9I/8ABxL/API1H/CS+J/+hf0j/wAHEv8A8jV2NFAHHf8ACS+J/wDoX9I/8HEv/wAj\r
-Uf8ACS+J/wDoX9I/8HEv/wAjV2NFAHHf8JL4n/6F/SP/AAcS/wDyNR/wkvif/oX9I/8ABxL/API1\r
-djRQBx3/AAkvif8A6F/SP/BxL/8AI1H/AAkvif8A6F/SP/BxL/8AI1djRQBx3/CS+J/+hf0j/wAH\r
-Ev8A8jUf8JL4n/6F/SP/AAcS/wDyNXY0UAcBJJrOq+IrPUNQsbCzhtbS4gC29687O0jwt3iTAAiP\r
-r1rv6KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii\r
-gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKA\r
-CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/" />\r
+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\r
+QUUAc/8A8IJ4P/6FTQ//AAXQ/wDxNH/CCeD/APoVND/8F0P/AMTXQUUAc/8A8IJ4P/6FTQ//AAXQ\r
+/wDxNH/CCeD/APoVND/8F0P/AMTXQUUAc/8A8IJ4P/6FTQ//AAXQ/wDxNY3haws9M8WeIbOwtILS\r
+1j1JdkMEYjRc2cBOFHAyST+NdzXHaH/yPHiT/sJJ/wCkVvQB2NFFFABRRRQAUUUUAFFFFABRRRQA\r
+UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABR\r
+RRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAGP4n0+81PRRBYCBrqO7tblFnkMaN5U\r
+8cpUsFYjIQjOD1rKn1/xTbzNE+gaMWXGcaxLj/0mrraKAOO/4SXxP/0L+kf+DiX/AORqP+El8T/9\r
+C/pH/g4l/wDkauxooA47/hJfE/8A0L+kf+DiX/5Go/4SXxP/ANC/pH/g4l/+Rq7GigDjv+El8T/9\r
+C/pH/g4l/wDkaj/hJfE//Qv6R/4OJf8A5GrsaKAOO/4SXxP/ANC/pH/g4l/+RqP+El8T/wDQv6R/\r
+4OJf/kauxooA47/hJfE//Qv6R/4OJf8A5Go/4SXxP/0L+kf+DiX/AORq7GigDjv+El8T/wDQv6R/\r
+4OJf/kam+GYr/wDt3Ub7UIbaCa/u/PEVvO0qoot44vvFEycxk9O9dnRQAUUUUAFFFFABRRRQAUUU\r
+UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH" />\r
</BODY>\r
</HTML>
\ No newline at end of file
-root ,root,stage1.adl-scic.org,19.01.2015 14:34,file:///home/dcalmel/.config/libreoffice/4;
\ No newline at end of file
+Moonspeak ,moonspeak,InDaMatrix,02.02.2015 10:49,file:///home/moonspeak/.config/libreoffice/4;
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?><project name="Untitled Gantt Project" company="" webLink="http://" view-date="2014-12-01" view-index="0" gantt-divider-location="383" resource-divider-location="300" version="2.7" locale="fr_FR">
+ <description/>
+ <view zooming-state="default:8" id="gantt-chart">
+ <field id="tpd3" name="Nom" width="67" order="0"/>
+ <field id="tpd4" name="Date de début" width="17" order="1"/>
+ <field id="tpd5" name="Date de fin" width="15" order="2"/>
+ <option id="taskLabelUp" value="name"/>
+ </view>
+ <view id="resource-table">
+ <field id="0" name="Nom" width="50" order="0"/>
+ <field id="1" name="Rôle par défaut" width="50" order="1"/>
+ </view>
+ <!-- -->
+ <calendars>
+ <day-types>
+ <day-type id="0"/>
+ <day-type id="1"/>
+ <default-week id="1" name="default" sun="1" mon="0" tue="0" wed="0" thu="0" fri="0" sat="1"/>
+ <only-show-weekends value="false"/>
+ <overriden-day-types/>
+ <days/>
+ </day-types>
+ </calendars>
+ <tasks empty-milestones="true">
+ <taskproperties>
+ <taskproperty id="tpd0" name="type" type="default" valuetype="icon"/>
+ <taskproperty id="tpd1" name="priority" type="default" valuetype="icon"/>
+ <taskproperty id="tpd2" name="info" type="default" valuetype="icon"/>
+ <taskproperty id="tpd3" name="name" type="default" valuetype="text"/>
+ <taskproperty id="tpd4" name="begindate" type="default" valuetype="date"/>
+ <taskproperty id="tpd5" name="enddate" type="default" valuetype="date"/>
+ <taskproperty id="tpd6" name="duration" type="default" valuetype="int"/>
+ <taskproperty id="tpd7" name="completion" type="default" valuetype="int"/>
+ <taskproperty id="tpd8" name="coordinator" type="default" valuetype="text"/>
+ <taskproperty id="tpd9" name="predecessorsr" type="default" valuetype="text"/>
+ </taskproperties>
+ <task id="0" name="AS - Transition CakePHP" color="#0033cc" meeting="false" start="2015-01-05" duration="10" complete="0" expand="true"/>
+ <task id="10" name="AS - Modification base" color="#0033cc" meeting="false" start="2015-01-05" duration="10" complete="0" expand="true"/>
+ <task id="7" name="AS/AC - Enrichissements informations envoyées" color="#0033cc" meeting="false" start="2015-01-12" duration="10" complete="0" expand="true"/>
+ <task id="3" name="AC - Etude solutions libres" color="#0033cc" meeting="false" start="2015-01-26" duration="10" complete="0" expand="true"/>
+ <task id="5" name="AS/AC - Sécurisation" color="#0033cc" meeting="false" start="2015-02-02" duration="15" complete="0" expand="true"/>
+ <task id="13" name="AS - Hébergement de test" color="#0033cc" meeting="false" start="2015-02-23" duration="5" complete="0" expand="true"/>
+ <task id="16" name="AS/AC - Tests de fonctionnement" color="#0033cc" meeting="false" start="2015-02-23" duration="10" complete="0" expand="true"/>
+ <task id="18" name="AC - Déploiement chez clients de test" color="#0033cc" meeting="false" start="2015-03-09" duration="15" complete="0" expand="true"/>
+ <task id="21" name="AS/Sugar - Etude intercommunication" color="#ff3300" meeting="false" start="2015-03-30" duration="15" complete="0" expand="true"/>
+ <task id="25" name="AS/Sugar - Mise en place du connecteur" color="#ff3300" meeting="false" start="2015-04-13" duration="15" complete="0" expand="true"/>
+ <task id="27" name="Sugar - Développements (Ajout notion exploitant)" color="#ff3300" meeting="false" start="2015-04-13" duration="30" complete="0" expand="true"/>
+ <task id="31" name="AS/Sugar - Tests de synchronisation" color="#ff3300" meeting="false" start="2015-04-20" duration="30" complete="0" expand="true"/>
+ <task id="54" name="AC - Déploiement et synchronisation générale" color="#ff3300" meeting="false" start="2015-06-01" duration="20" complete="0" expand="true"/>
+ <task id="46" name="AUTOMATISER PATCH" color="#009900" meeting="false" start="2015-06-29" duration="70" complete="0" expand="true"/>
+ <task id="49" name="AUTOMATISER MISE À JOUR" color="#330099" meeting="false" start="2015-10-05" duration="64" complete="0" expand="true"/>
+ </tasks>
+ <resources>
+ <resource id="0" name="David CALMEL" function="Default:1" contacts="david.calmel@adullact-projet.coop" phone=""/>
+ </resources>
+ <allocations>
+ <allocation task-id="0" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="10" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="7" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="3" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="5" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="13" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="16" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="18" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="21" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="25" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="31" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="46" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="49" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ <allocation task-id="54" resource-id="0" function="Default:1" responsible="true" load="100.0"/>
+ </allocations>
+ <vacations>
+ <vacation start="2014-12-22" end="2014-12-27" resourceid="0"/>
+ </vacations>
+ <taskdisplaycolumns>
+ <displaycolumn property-id="tpd2" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd7" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd12" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd6" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd10" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd11" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd1" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd9" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd8" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd0" order="-1" width="75" visible="false"/>
+ <displaycolumn property-id="tpd3" order="0" width="255" visible="true"/>
+ <displaycolumn property-id="tpd4" order="1" width="66" visible="true"/>
+ <displaycolumn property-id="tpd5" order="2" width="58" visible="true"/>
+ </taskdisplaycolumns>
+ <previous/>
+ <roles roleset-name="Default"/>
+</project>