diff --git a/.hgignore b/.hgignore
index 4a0311dcc..125eff13c 100644
--- a/.hgignore
+++ b/.hgignore
@@ -206,3 +206,5 @@ code/ryzom/server/src/ryzom_admin_service/ryzom_admin_service
code/ryzom/server/src/ryzom_naming_service/ryzom_naming_service
code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service
code/ryzom/server/src/tick_service/tick_service
+# WebTT temp dir
+code/ryzom/tools/server/www/webtt/app/tmp
diff --git a/code/ryzom/tools/server/www/webtt/app/config/core.php b/code/ryzom/tools/server/www/webtt/app/config/core.php
index 517e32d0d..6bd8d65c6 100644
--- a/code/ryzom/tools/server/www/webtt/app/config/core.php
+++ b/code/ryzom/tools/server/www/webtt/app/config/core.php
@@ -85,7 +85,7 @@
*
* [Note Routing.admin is deprecated in 1.3. Use Routing.prefixes instead]
*/
- //Configure::write('Routing.prefixes', array('admin'));
+ Configure::write('Routing.prefixes', array('admin'));
/**
* Turn off all caching application-wide.
@@ -201,12 +201,12 @@
/**
* A random string used in security hashing methods.
*/
- Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
+ Configure::write('Security.salt', '3928c5uM398u4R39m4u8c3m493U49');
/**
* A random numeric string (digits only) used to encrypt/decrypt strings.
*/
- Configure::write('Security.cipherSeed', '76859309657453542496749683645');
+ Configure::write('Security.cipherSeed', '849713027853098175087095830289');
/**
* Apply timestamps with the last modified time to static assets (js, css, images).
diff --git a/code/ryzom/tools/server/www/webtt/app/config/database.php b/code/ryzom/tools/server/www/webtt/app/config/database.php
new file mode 100644
index 000000000..ca5057ba0
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/config/database.php
@@ -0,0 +1,18 @@
+ 'mysqli',
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'login' => 'webtt',
+ 'password' => 'webtt77',
+ 'database' => 'webtt2',
+ 'encoding' => 'y'
+ );
+ var $raw_files = array(
+ 'driver' => "",
+ 'datasource' => 'raw_files',
+ );
+}
+?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/app_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/app_controller.php
new file mode 100644
index 000000000..458137748
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/app_controller.php
@@ -0,0 +1,37 @@
+FileIdentifier->recursive = 0;
+ $this->set('fileIdentifiers', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid file identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('fileIdentifier', $this->FileIdentifier->read(null, $id));
+ }
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->FileIdentifier->create();
+ if ($this->FileIdentifier->save($this->data)) {
+ $this->Session->setFlash(__('The file identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The file identifier could not be saved. Please, try again.', true));
+ }
+ }
+ $translationFiles = $this->FileIdentifier->TranslationFile->find('list');
+ $identifiers = $this->FileIdentifier->Identifier->find('list');
+ $this->set(compact('translationFiles', 'identifiers'));
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid file identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->FileIdentifier->save($this->data)) {
+ $this->Session->setFlash(__('The file identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The file identifier could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->FileIdentifier->read(null, $id);
+ }
+ $translationFiles = $this->FileIdentifier->TranslationFile->find('list');
+ $identifiers = $this->FileIdentifier->Identifier->find('list');
+ $this->set(compact('translationFiles', 'identifiers'));
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for file identifier', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->FileIdentifier->delete($id)) {
+ $this->Session->setFlash(__('File identifier deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('File identifier was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->FileIdentifier->recursive = 0;
+ $this->set('fileIdentifiers', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid file identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('fileIdentifier', $this->FileIdentifier->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->FileIdentifier->create();
+ if ($this->FileIdentifier->save($this->data)) {
+ $this->Session->setFlash(__('The file identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The file identifier could not be saved. Please, try again.', true));
+ }
+ }
+ $translationFiles = $this->FileIdentifier->TranslationFile->find('list');
+ $identifiers = $this->FileIdentifier->Identifier->find('list');
+ $this->set(compact('translationFiles', 'identifiers'));
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid file identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->FileIdentifier->save($this->data)) {
+ $this->Session->setFlash(__('The file identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The file identifier could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->FileIdentifier->read(null, $id);
+ }
+ $translationFiles = $this->FileIdentifier->TranslationFile->find('list');
+ $identifiers = $this->FileIdentifier->Identifier->find('list');
+ $this->set(compact('translationFiles', 'identifiers'));
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for file identifier', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->FileIdentifier->delete($id)) {
+ $this->Session->setFlash(__('File identifier deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('File identifier was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/identifiers_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/identifiers_controller.php
new file mode 100644
index 000000000..cae46aa55
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/identifiers_controller.php
@@ -0,0 +1,124 @@
+Identifier->recursive = 0;
+ $this->set('identifiers', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('identifier', $this->Identifier->read(null, $id));
+ }
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->Identifier->create();
+ if ($this->Identifier->save($this->data)) {
+ $this->Session->setFlash(__('The identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The identifier could not be saved. Please, try again.', true));
+ }
+ }
+ $languages = $this->Identifier->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Identifier->save($this->data)) {
+ $this->Session->setFlash(__('The identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The identifier could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Identifier->read(null, $id);
+ }
+ $languages = $this->Identifier->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for identifier', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Identifier->delete($id)) {
+ $this->Session->setFlash(__('Identifier deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Identifier was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->Identifier->recursive = 0;
+ $this->set('identifiers', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('identifier', $this->Identifier->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->Identifier->create();
+ if ($this->Identifier->save($this->data)) {
+ $this->Session->setFlash(__('The identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The identifier could not be saved. Please, try again.', true));
+ }
+ }
+ $languages = $this->Identifier->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid identifier', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Identifier->save($this->data)) {
+ $this->Session->setFlash(__('The identifier has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The identifier could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Identifier->read(null, $id);
+ }
+ $languages = $this->Identifier->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for identifier', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Identifier->delete($id)) {
+ $this->Session->setFlash(__('Identifier deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Identifier was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/imported_translation_files_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/imported_translation_files_controller.php
new file mode 100644
index 000000000..77576c003
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/imported_translation_files_controller.php
@@ -0,0 +1,209 @@
+ImportedTranslationFile->recursive = 0;
+ $this->set('importedTranslationFiles', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid translation file', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('importedTranslationFile', $this->ImportedTranslationFile->read(null, $id));
+// var_dump($this->ImportedTranslationFile->RawFile);
+ }
+
+ function admin_import($filename = null) {
+// $this->view = "index";
+ App::import("Vendor","UxtParser", array("file" => 'UxtParser.php'));
+/* if (!$filename) {
+ $this->Session->setFlash(__('Invalid file', true));
+ $this->redirect(array('action' => 'index'));
+ return 0;
+ }*/
+ $filename="diff/pl_diff_4DEC868A.uxt";
+ $translationFile = $this->ImportedTranslationFile->find('first', array('conditions' => array('ImportedTranslationFile.filename' => $filename)));
+ if ($translationFile)
+ {
+ $this->Session->setFlash(__('Translation file already imported', true));
+ $this->redirect(array('action' => 'index'));
+ return 0;
+ }
+// var_dump($file);
+ $parser = new UxtParser();
+ $parsedFile = $parser->parseFile($filename);
+// var_dump($parsedFile);
+ $arr = explode("_", basename($filename, ".uxt"));
+// var_dump($arr);
+ $language_id = 1;
+
+ $this->ImportedTranslationFile->create();
+ $data['ImportedTranslationFile']['language_id'] = $language_id;
+ $data['ImportedTranslationFile']['filename'] = $filename;
+ //$this->ImportedTranslationFile->save($data);
+ foreach ($parsedFile as $ent)
+ {
+ $fi_data = array();
+ if ($ent['type'] != "string")
+ continue;
+
+
+ $i_data['language_id'] = $language_id;
+ $i_data['translation_index'] = $ent['index'];
+ $i_data['reference_string'] = $ent['string'];
+ unset($this->ImportedTranslationFile->Language->Identifier->id);
+ $identifier = $this->ImportedTranslationFile->Language->Identifier->find('first',array('conditions' => array('Identifier.identifier' => $ent['identifier'], 'Identifier.language_id' => $language_id)));
+ if ($identifier)
+ {
+// var_dump($identifier);
+ $i_data['id']=$identifier['Identifier']['id'];
+ }
+ else
+ {
+ $i_data['identifier'] = $ent['identifier'];
+ $i_data['translated'] = false;
+ }
+ var_dump($i_data);
+ $this->ImportedTranslationFile->Language->Identifier->save(array('Identifier' => $i_data));
+ $identifier_id = $this->ImportedTranslationFile->Language->Identifier->id;
+ var_dump($identifier_id);
+
+ unset($this->ImportedTranslationFile->FileIdentifier->id);
+ //TODO - set FileIdentifier['id'] if we import already imported file (imported imported file temporarly disabled)
+// $identifier = $this->ImportedTranslationFile->FileIdentifier->find('first',array('conditions' => array('FileIdentifier.identifier' => $ent['identifier'], 'FileIdentifier.translation_file_id' => $)));
+// $data['FileIdentifier']['translation_file_id'] = $this->ImportedTranslationFile->id;
+ if ($ent['diff'])
+ $fi_data['command'] = "DIFF " . mb_strtoupper($ent['diff']);
+ $fi_data['translation_index'] = $ent['index'];
+// $data['FileIdentifier']['identifier_id'] = ;
+ $fi_data['reference_string'] = $ent['string'];
+ $fi_data['identifier_id'] = $identifier_id;
+
+// $this->ImportedTranslationFile->FileIdentifier->create();
+// $this->ImportedTranslationFile->FileIdentifier->save($data);
+ $data['FileIdentifier'][] = $fi_data;
+// $l_data['Language']['id'] = $language_id;
+// $l_data['Identifier'][] = $i_data;
+// $data['Identifier'][] = $i_data;
+ }
+// var_dump($data);
+// $this->ImportedTranslationFile->Language->saveAll($l_data);
+ $this->ImportedTranslationFile->saveAll($data);
+ $this->Session->setFlash(__('Translation file imported', true));
+ $this->redirect(array('action' => 'view', $this->ImportedTranslationFile->id));
+ $this->ImportedTranslationFile->recursive = 0;
+ $this->set('importedTranslationFiles', $this->paginate());
+// $this->render('index');
+ }
+
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->ImportedTranslationFile->create();
+ if ($this->ImportedTranslationFile->save($this->data)) {
+ $this->Session->setFlash(__('The translation file has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation file could not be saved. Please, try again.', true));
+ }
+ }
+ $languages = $this->ImportedTranslationFile->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid translation file', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->ImportedTranslationFile->save($this->data)) {
+ $this->Session->setFlash(__('The translation file has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation file could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->ImportedTranslationFile->read(null, $id);
+ }
+ $languages = $this->ImportedTranslationFile->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for translation file', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->ImportedTranslationFile->delete($id)) {
+ $this->Session->setFlash(__('Translation file deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Translation file was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->ImportedTranslationFile->recursive = 0;
+ $this->set('importedTranslationFiles', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid translation file', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('translationFile', $this->ImportedTranslationFile->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->ImportedTranslationFile->create();
+ if ($this->ImportedTranslationFile->save($this->data)) {
+ $this->Session->setFlash(__('The translation file has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation file could not be saved. Please, try again.', true));
+ }
+ }
+ $languages = $this->ImportedTranslationFile->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid translation file', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->ImportedTranslationFile->save($this->data)) {
+ $this->Session->setFlash(__('The translation file has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation file could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->ImportedTranslationFile->read(null, $id);
+ }
+ $languages = $this->ImportedTranslationFile->Language->find('list');
+ $this->set(compact('languages'));
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for translation file', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->ImportedTranslationFile->delete($id)) {
+ $this->Session->setFlash(__('Translation file deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Translation file was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/languages_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/languages_controller.php
new file mode 100644
index 000000000..f88ee9739
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/languages_controller.php
@@ -0,0 +1,121 @@
+Language->recursive = 0;
+ $this->set('languages', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('language', $this->Language->read(null, $id));
+ }
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->Language->create();
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Language->read(null, $id);
+ }
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for language', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Language->delete($id)) {
+ $this->Session->setFlash(__('Language deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Language was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->Language->recursive = 0;
+ $this->set('languages', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('language', $this->Language->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->Language->create();
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Language->read(null, $id);
+ }
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for language', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Language->delete($id)) {
+ $this->Session->setFlash(__('Language deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Language was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/languages_controller.php.bak b/code/ryzom/tools/server/www/webtt/app/controllers/languages_controller.php.bak
new file mode 100644
index 000000000..46234b733
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/languages_controller.php.bak
@@ -0,0 +1,125 @@
+Language->recursive = 0;
+ $this->set('languages', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('language', $this->Language->read(null, $id));
+/* $options = array('Language.id' => $id, 'recursive' => 1,
+ "joins" => array(
+ array('table' => '
+ ),
+ );
+ var_dump($this);
+ $this->set('language', $bumz = $this->Language->find('first', $options));
+var_dump($bumz);*/
+// $this->set('identifier', $this->Language->TranslationFile->read(null, $id));
+ }
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->Language->create();
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Language->read(null, $id);
+ }
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for language', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Language->delete($id)) {
+ $this->Session->setFlash(__('Language deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Language was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->Language->recursive = 0;
+ $this->set('languages', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('language', $this->Language->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->Language->create();
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid language', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Language->save($this->data)) {
+ $this->Session->setFlash(__('The language has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The language could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Language->read(null, $id);
+ }
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for language', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Language->delete($id)) {
+ $this->Session->setFlash(__('Language deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Language was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/raw_files_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/raw_files_controller.php
new file mode 100644
index 000000000..e49bdf14f
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/raw_files_controller.php
@@ -0,0 +1,154 @@
+RawFile->recursive = 1;
+// var_dump($this->RawFile->find('count'));
+// $db =& ConnectionManager::getDataSource($this->RawFile->useDbConfig);
+// var_dump($db->calculate($this->RawFile, 'count'));
+ $this->set('rawFiles', $this->paginate());
+// var_dump($this->paginate());
+ }
+
+ function admin_index() {
+ $this->index();
+ }
+
+ function listdir($ext = null) {
+ $this->RawFile->recursive = 0;
+ $this->set('rawFiles', $this->paginate(array("ext" => $ext)));
+// var_dump($this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid raw file', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('rawFile', $this->RawFiles->read(null, $id));
+ }
+
+ function admin_import($dir = null, $filename = null) {
+// $this->view = "index";
+// App::import("Vendor","UxtParser", array("file" => 'UxtParser.php'));
+ if (!$filename) {
+ $this->Session->setFlash(__('Invalid file', true));
+ $this->redirect(array('action' => 'index'));
+ return 0;
+ }
+ if (!$this->RawFile->open($dir, $filename))
+ {
+ $this->Session->setFlash(__('Can\'t open file', true));
+ $this->redirect(array('action' => 'index'));
+ return 0;
+ }
+ $importedTranslationFileModel = $this->RawFile->ImportedTranslationFile;
+ $languageModel = $importedTranslationFileModel->Language;
+ $identifierModel = $languageModel->Identifier;
+ $fileIdentifierModel = $importedTranslationFileModel->FileIdentifier;
+
+// $filename="diff/pl_diff_4DEC868A.uxt";
+ $importedTranslationFile = $importedTranslationFileModel->find('first', array('conditions' => array('ImportedTranslationFile.filename' => $dir . DS . $filename)));
+/* var_dump($translationFile);
+ return 0;*/
+ if ($importedTranslationFile)
+ {
+ $this->Session->setFlash(__('Translation file already imported', true));
+ $this->redirect(array('action' => 'index'));
+ return 0;
+ }
+// var_dump($file);
+// $parser = new UxtParser();
+ $parsedFile = $this->RawFile->parseFile($filename);
+// var_dump($parsedFile);
+// $arr = explode("_", basename($filename, ".uxt"));
+// var_dump($arr);
+
+// $language_id = 1;
+ $languageCode = $this->RawFile->getLanguageCode($filename);
+ if (!$languageCode)
+ {
+ $this->Session->setFlash(__('Can\'t identify language', true));
+ $this->redirect(array('action' => 'index'));
+ return 0;
+ }
+ $language = $importedTranslationFileModel->Language->find('first', array('conditions' => array('code' => $languageCode)));
+ $language_id = $language['Language']['id'];
+ if (!$language_id)
+ {
+ $this->Session->setFlash(__('Can\'t find language in database', true));
+ $this->redirect(array('action' => 'index'));
+ return 0;
+ }
+ else
+ {
+// var_dump($language_id);
+ }
+
+// return 0;
+
+ $importedTranslationFileModel->create();
+ $data['ImportedTranslationFile']['language_id'] = $language_id;
+ $data['ImportedTranslationFile']['filename'] = $dir . DS . $filename;
+ //$this->ImportedTranslationFile->save($data);
+ foreach ($parsedFile as $ent)
+ {
+ $fi_data = array();
+ if ($ent['type'] != "string")
+ continue;
+
+ $i_data['language_id'] = $language_id;
+ $i_data['translation_index'] = $ent['index'];
+ $i_data['reference_string'] = $ent['string'];
+
+ unset($identifierModel->id);
+ $identifier = $identifierModel->find('first',array('conditions' => array('Identifier.identifier' => $ent['identifier'], 'Identifier.language_id' => $language_id)));
+ if ($identifier)
+ {
+// var_dump($identifier);
+ $i_data['id']=$identifier['Identifier']['id'];
+ }
+ else
+ {
+ $i_data['identifier'] = $ent['identifier'];
+ $i_data['translated'] = false;
+ }
+// var_dump($i_data);
+ $identifierModel->save(array('Identifier' => $i_data));
+ $identifier_id = $identifierModel->id;
+// var_dump($identifier_id);
+
+ unset($fileIdentifierModel->id);
+ //TODO - set FileIdentifier['id'] if we import already imported file (importing imported file temporarly disabled)
+// $identifier = $this->ImportedTranslationFile->FileIdentifier->find('first',array('conditions' => array('FileIdentifier.identifier' => $ent['identifier'], 'FileIdentifier.translation_file_id' => $)));
+// $data['FileIdentifier']['translation_file_id'] = $this->ImportedTranslationFile->id;
+ if ($ent['diff'])
+ $fi_data['command'] = "DIFF " . mb_strtoupper($ent['diff']);
+ $fi_data['translation_index'] = $ent['index'];
+// $data['FileIdentifier']['identifier_id'] = ;
+ $fi_data['reference_string'] = $ent['string'];
+ $fi_data['identifier_id'] = $identifier_id;
+
+// $this->ImportedTranslationFile->FileIdentifier->create();
+// $this->ImportedTranslationFile->FileIdentifier->save($data);
+ $data['FileIdentifier'][] = $fi_data;
+// $l_data['Language']['id'] = $language_id;
+// $l_data['Identifier'][] = $i_data;
+// $data['Identifier'][] = $i_data;
+ }
+// var_dump($data);
+// $this->ImportedTranslationFile->Language->saveAll($l_data);
+ $importedTranslationFileModel->saveAll($data);
+ $this->Session->setFlash(__('Translation file imported', true));
+ $this->redirect(array('controller' => 'imported_translation_files', 'action' => 'view', $importedTranslationFileModel->id));
+// $this->ImportedTranslationFile->recursive = 0;
+// $this->set('importedTranslationFiles', $this->paginate());
+// $this->render('index');
+ }
+
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/translations_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/translations_controller.php
new file mode 100644
index 000000000..b565b925a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/translations_controller.php
@@ -0,0 +1,130 @@
+Translation->recursive = 0;
+ $this->set('translations', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid translation', true));
+ $this->redirect(array('action' => 'index'));
+ }
+// $this->recursive=2;
+ $this->set('translation', $bumz = $this->Translation->read(null, $id));
+// var_dump($bumz);
+ }
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->Translation->create();
+ if ($this->Translation->save($this->data)) {
+ $this->Session->setFlash(__('The translation has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation could not be saved. Please, try again.', true));
+ }
+ }
+ $identifiers = $this->Translation->Identifier->find('list');
+ $users = $this->Translation->User->find('list');
+ $this->set(compact('identifiers', 'users'));
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid translation', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Translation->save($this->data)) {
+ $this->Session->setFlash(__('The translation has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Translation->read(null, $id);
+ }
+ $identifiers = $this->Translation->Identifier->find('list');
+ $users = $this->Translation->User->find('list');
+ $this->set(compact('identifiers', 'users'));
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for translation', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Translation->delete($id)) {
+ $this->Session->setFlash(__('Translation deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Translation was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->Translation->recursive = 0;
+ $this->set('translations', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid translation', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('translation', $this->Translation->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->Translation->create();
+ if ($this->Translation->save($this->data)) {
+ $this->Session->setFlash(__('The translation has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation could not be saved. Please, try again.', true));
+ }
+ }
+ $identifiers = $this->Translation->Identifier->find('list');
+ $users = $this->Translation->User->find('list');
+ $this->set(compact('identifiers', 'users'));
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid translation', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Translation->save($this->data)) {
+ $this->Session->setFlash(__('The translation has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The translation could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Translation->read(null, $id);
+ }
+ $identifiers = $this->Translation->Identifier->find('list');
+ $users = $this->Translation->User->find('list');
+ $this->set(compact('identifiers', 'users'));
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for translation', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Translation->delete($id)) {
+ $this->Session->setFlash(__('Translation deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Translation was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/users_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/users_controller.php
new file mode 100644
index 000000000..a7d996e70
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/users_controller.php
@@ -0,0 +1,116 @@
+User->recursive = 0;
+ $this->set('users', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid user', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('user', $this->User->read(null, $id));
+ }
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->User->create();
+ if ($this->User->save($this->data)) {
+ $this->Session->setFlash(__('The user has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
+ }
+ }
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid user', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->User->save($this->data)) {
+ $this->Session->setFlash(__('The user has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->User->read(null, $id);
+ }
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for user', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->User->delete($id)) {
+ $this->Session->setFlash(__('User deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('User was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->User->recursive = 0;
+ $this->set('users', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid user', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('user', $this->User->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->User->create();
+ if ($this->User->save($this->data)) {
+ $this->Session->setFlash(__('The user has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
+ }
+ }
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid user', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->User->save($this->data)) {
+ $this->Session->setFlash(__('The user has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->User->read(null, $id);
+ }
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for user', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->User->delete($id)) {
+ $this->Session->setFlash(__('User deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('User was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/controllers/votes_controller.php b/code/ryzom/tools/server/www/webtt/app/controllers/votes_controller.php
new file mode 100644
index 000000000..25e63147f
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/controllers/votes_controller.php
@@ -0,0 +1,128 @@
+Vote->recursive = 0;
+ $this->set('votes', $this->paginate());
+ }
+
+ function view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid vote', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('vote', $this->Vote->read(null, $id));
+ }
+
+ function add() {
+ if (!empty($this->data)) {
+ $this->Vote->create();
+ if ($this->Vote->save($this->data)) {
+ $this->Session->setFlash(__('The vote has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The vote could not be saved. Please, try again.', true));
+ }
+ }
+ $translations = $this->Vote->Translation->find('list');
+ $users = $this->Vote->User->find('list');
+ $this->set(compact('translations', 'users'));
+ }
+
+ function edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid vote', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Vote->save($this->data)) {
+ $this->Session->setFlash(__('The vote has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The vote could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Vote->read(null, $id);
+ }
+ $translations = $this->Vote->Translation->find('list');
+ $users = $this->Vote->User->find('list');
+ $this->set(compact('translations', 'users'));
+ }
+
+ function delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for vote', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Vote->delete($id)) {
+ $this->Session->setFlash(__('Vote deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Vote was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ function admin_index() {
+ $this->Vote->recursive = 0;
+ $this->set('votes', $this->paginate());
+ }
+
+ function admin_view($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid vote', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ $this->set('vote', $this->Vote->read(null, $id));
+ }
+
+ function admin_add() {
+ if (!empty($this->data)) {
+ $this->Vote->create();
+ if ($this->Vote->save($this->data)) {
+ $this->Session->setFlash(__('The vote has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The vote could not be saved. Please, try again.', true));
+ }
+ }
+ $translations = $this->Vote->Translation->find('list');
+ $users = $this->Vote->User->find('list');
+ $this->set(compact('translations', 'users'));
+ }
+
+ function admin_edit($id = null) {
+ if (!$id && empty($this->data)) {
+ $this->Session->setFlash(__('Invalid vote', true));
+ $this->redirect(array('action' => 'index'));
+ }
+ if (!empty($this->data)) {
+ if ($this->Vote->save($this->data)) {
+ $this->Session->setFlash(__('The vote has been saved', true));
+ $this->redirect(array('action' => 'index'));
+ } else {
+ $this->Session->setFlash(__('The vote could not be saved. Please, try again.', true));
+ }
+ }
+ if (empty($this->data)) {
+ $this->data = $this->Vote->read(null, $id);
+ }
+ $translations = $this->Vote->Translation->find('list');
+ $users = $this->Vote->User->find('list');
+ $this->set(compact('translations', 'users'));
+ }
+
+ function admin_delete($id = null) {
+ if (!$id) {
+ $this->Session->setFlash(__('Invalid id for vote', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ if ($this->Vote->delete($id)) {
+ $this->Session->setFlash(__('Vote deleted', true));
+ $this->redirect(array('action'=>'index'));
+ }
+ $this->Session->setFlash(__('Vote was not deleted', true));
+ $this->redirect(array('action' => 'index'));
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/app_model.php b/code/ryzom/tools/server/www/webtt/app/models/app_model.php
new file mode 100644
index 000000000..6dd28c9e0
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/app_model.php
@@ -0,0 +1,36 @@
+ 'Datasources.CsvSource',
+ * 'path' => '/path/to/file', // Path
+ * 'extension' => 'csv', // File extension
+ * 'readonly' => true, // Mark for read only access
+ * 'recursive' => false // Only false is supported at the moment
+ * );
+ */
+
+if (!class_exists('Folder')) {
+ App::import('Core', 'Folder');
+}
+
+if (!class_exists('File')) {
+ App::import('Core', 'File');
+}
+
+/**
+ * CSVSource Datasource
+ *
+ * @package datasources
+ * @subpackage datasources.models.datasources
+ */
+class RawFilesSource extends DataSource {
+
+/**
+ * Description
+ *
+ * @var string
+ */
+ public $description = 'File Data Source';
+
+/**
+ * Column delimiter
+ *
+ * @var string
+ */
+ public $delimiter = ';';
+
+/**
+ * Maximum Columns
+ *
+ * @var integer
+ */
+ public $maxCol = 0;
+
+/**
+ * Field Names
+ *
+ * @var mixed
+ */
+ public $fields = null;
+
+/**
+ * File Handle
+ *
+ * @var mixed
+ */
+ public $handle = false;
+
+/**
+ * Page to start on
+ *
+ * @var integer
+ */
+ public $page = 1;
+
+/**
+ * Limit of records
+ *
+ * @var integer
+ */
+ public $limit = 99999;
+
+/**
+ * Default configuration.
+ *
+ * @var array
+ */
+ var $_baseConfig = array(
+ 'datasource' => 'raw_files',
+ 'path' => '/home/kaczorek/projects/webtt/distfiles/translation',
+ 'extension' => 'uxt',
+ 'readonly' => true,
+ 'recursive' => true);
+
+ protected $_schema = array(
+ 'files' => array(
+ 'filename' => array(
+ 'type' => 'string',
+ 'null' => false,
+ 'key' => 'primary',
+ 'lenght' => 255
+ )
+ )
+ );
+/**
+ * Constructor
+ *
+ * @param string $config Configuration array
+ * @param boolean $autoConnect Automatically connect to / open the file
+ */
+ public function __construct($config = null, $autoConnect = true) {
+ $this->debug = Configure::read('debug') > 0;
+ $this->fullDebug = Configure::read('debug') > 1;
+ parent::__construct($config);
+ if ($autoConnect) {
+ $this->connect();
+ }
+ }
+
+/**
+ * Connects to the mailbox using options in the given configuration array.
+ *
+ * @return boolean True if the file could be opened.
+ */
+ public function connect() {
+ $this->connected = false;
+
+ if ($this->config['readonly']) {
+ $create = false;
+ $mode = 0;
+ } else {
+ $create = true;
+ $mode = 0777;
+ }
+
+ $this->connection =& new Folder($this->config['path'], $create, $mode);
+ if ($this->connection) {
+ $this->handle = array();
+ $this->connected = true;
+ }
+
+ return $this->connected;
+ }
+
+/**
+ * List available sources
+ *
+ * @return array of available CSV files
+ */
+ public function listSources() {
+ $this->config['database'] = 'csv';
+ $cache = parent::listSources();
+ if ($cache !== null) {
+ return $cache;
+ }
+
+ $extPattern = '\.' . preg_quote($this->config['extension']);
+ if ($this->config['recursive']) {
+ $list = $this->connection->findRecursive('.*' . $extPattern, true);
+ foreach($list as &$item) {
+ $item = mb_substr($item, mb_strlen($this->config['path'] . DS));
+ }
+ } else {
+ $list = $this->connection->find('.*' . $extPattern, true);
+ }
+
+ foreach ($list as &$item) {
+ $item = preg_replace('/' . $extPattern . '$/i', '', $item);
+ }
+
+ parent::listSources($list);
+ unset($this->config['database']);
+ return $list;
+ }
+
+/**
+ * Returns a Model description (metadata) or null if none found.
+ *
+ * @return mixed
+ */
+ public function describe($model) {
+ $this->__getDescriptionFromFirstLine($model);
+ return $this->fields;
+ }
+
+/**
+ * Get Description from First Line, and store into class vars
+ *
+ * @param Model $model
+ * @return boolean True, Success
+ */
+ private function __getDescriptionFromFirstLine($model) {
+ $filename = $model->table . '.' . $this->config['extension'];
+ $handle = fopen($this->config['path'] . DS . $filename, 'r');
+ $line = rtrim(fgets($handle));
+ $data_comma = explode(',', $line);
+ $data_semicolon = explode(';', $line);
+
+ if (count($data_comma) > count($data_semicolon)) {
+ $this->delimiter = ',';
+ $this->fields = $data_comma;
+ $this->maxCol = count($data_comma);
+ } else {
+ $this->delimiter = ';';
+ $this->fields = $data_semicolon;
+ $this->maxCol = count($data_semicolon);
+ }
+ fclose($handle);
+ return true;
+ }
+
+/**
+ * Close file handle
+ *
+ * @return null
+ */
+ public function close() {
+ if ($this->connected) {
+ if ($this->handle) {
+ foreach($this->handle as $h) {
+ @fclose($h);
+ }
+ $this->handle = false;
+ }
+ $this->connected = false;
+ }
+ }
+
+ public function read(&$model, $queryData = array(), $recursive = null) {
+ if ($queryData["conditions"] && $queryData["conditions"]["ext"])
+ $extension = $queryData["conditions"]["ext"];
+ else
+ $extension = $this->config['extension'];
+
+ $extPattern = '\.' . preg_quote($extension);
+ if ($this->config['recursive']) {
+ $list = $this->connection->findRecursive('.*' . $extPattern, true);
+ foreach($list as &$item) {
+ $item = mb_substr($item, mb_strlen($this->connection->realpath($this->config['path']) . DS));
+ }
+ unset($item);
+ } else {
+ $list = $this->connection->find('.*' . $extPattern, true);
+ }
+
+ $nlist = array();
+ foreach ($list as $item) {
+ $file = new File($path = $this->config['path'] . DS . $item, false);
+// var_dump($item);
+// $item = preg_replace('/' . $extPattern . '$/i', '', $item);
+ $resultSet[] = array(
+ $model->alias => array(
+ 'filename' => $item,
+ 'size' => $file->size(),
+ 'modified' => $file->lastChange(),
+ ),
+ );
+ }
+ if ($model->findQueryType === 'count') {
+ return array(array(array('count' => count($resultSet))));
+ }
+
+ return $resultSet;
+ }
+/**
+ * Read Data
+ *
+ * @param Model $model
+ * @param array $queryData
+ * @param integer $recursive Number of levels of association
+ * @return mixed
+ */
+ public function read_z(&$model, $queryData = array(), $recursive = null) {
+ $config = $this->config;
+ $filename = $config['path'] . DS . $model->table . '.' . $config['extension'];
+ if (!Set::extract($this->handle, $model->table)) {
+ $this->handle[$model->table] = fopen($filename, 'r');
+ } else {
+ fseek($this->handle[$model->table], 0, SEEK_SET) ;
+ }
+ $queryData = $this->__scrubQueryData($queryData);
+
+ if (isset($queryData['limit']) && !empty($queryData['limit'])) {
+ $this->limit = $queryData['limit'];
+ }
+
+ if (isset($queryData['page']) && !empty($queryData['page'])) {
+ $this->page = $queryData['page'];
+ }
+
+ if (empty($queryData['fields'])) {
+ $fields = $this->fields;
+ $allFields = true;
+ } else {
+ $fields = $queryData['fields'];
+ $allFields = false;
+ $_fieldIndex = array();
+ $index = 0;
+ // generate an index array of all wanted fields
+ foreach($this->fields as $field) {
+ if (in_array($field, $fields)) {
+ $_fieldIndex[] = $index;
+ }
+ $index++;
+ }
+ }
+
+ $lineCount = 0;
+ $recordCount = 0;
+ $findCount = 0;
+ $resultSet = array();
+
+ // Daten werden aus der Datei in ein Array $data gelesen
+ while (($data = fgetcsv($this->handle[$model->table], 8192, $this->delimiter)) !== FALSE) {
+ if ($lineCount == 0) {
+ $lineCount++;
+ continue;
+ } else {
+ // Skip over records, that are not complete
+ if (count($data) < $this->maxCol) {
+ continue;
+ }
+
+ $record = array();
+ $i = 0;
+ foreach($this->fields as $field) {
+ $record[$model->alias][$field] = $data[$i++];
+ }
+
+ if ($this->__checkConditions($record, $queryData['conditions'], $model)) {
+ // Compute the virtual pagenumber
+ $_page = floor($findCount / $this->limit) + 1;
+ if ($this->page <= $_page) {
+ if (!$allFields) {
+ $record = array();
+ if (count($_fieldIndex) > 0) {
+ foreach($_fieldIndex as $i) {
+ $record[$model->alias][$this->fields[$i]] = $data[$i];
+ }
+ }
+ }
+ $resultSet[] = $record ;
+ $recordCount++;
+ }
+ }
+ unset($record);
+ $findCount++;
+
+ if ($recordCount >= $this->limit) {
+ break;
+ }
+ }
+ }
+
+ if ($model->findQueryType === 'count') {
+ return array(array(array('count' => count($resultSet))));
+ }
+ return $resultSet;
+ }
+
+/**
+ * Private helper method to remove query metadata in given data array.
+ *
+ * @param array $data Data
+ * @return array Cleaned Data
+ */
+ private function __scrubQueryData($data) {
+ foreach (array('conditions', 'fields', 'joins', 'order', /*'limit', 'offset',*/ 'group') as $key) {
+ if (!isset($data[$key]) || empty($data[$key])) {
+ $data[$key] = array();
+ }
+ }
+ if (!isset($data['limit']) || empty($data['limit'])) {
+ $data['limit'] = PHP_INT_MAX;
+ }
+ if (!isset($data['offset']) || empty($data['offset'])) {
+ $data['offset'] = 0;
+ }
+ return $data;
+ }
+
+/**
+ * Private helper method to check conditions.
+ *
+ * @param array $record
+ * @param array $conditions
+ * @return bool
+ */
+ private function __checkConditions($record, $conditions, $model) {
+ $result = true;
+ foreach ($conditions as $name => $value) {
+ $alias = $model->alias;
+ if (strpos($name, '.') !== false) {
+ list($alias, $name) = explode('.', $name);
+ }
+
+ if (strtolower($name) === 'or') {
+ $cond = $value;
+ $result = false;
+ foreach ($cond as $name => $value) {
+ if (Set::matches($this->__createRule($name, $value), $record[$alias])) {
+ return true;
+ }
+ }
+ } else {
+ if (!Set::matches($this->__createRule($name, $value), $record[$alias])) {
+ return false;
+ }
+ }
+ }
+ return $result;
+ }
+
+/**
+ * Private helper method to crete rule.
+ *
+ * @param string $name
+ * @param string $value
+ * @return string
+ */
+ private function __createRule($name, $value) {
+ if (strpos($name, ' ') !== false) {
+ return array(str_replace(' ', '', $name) . $value);
+ }
+ return array("{$name}={$value}");
+ }
+
+/**
+ * Calculate
+ *
+ * @param Model $model
+ * @param mixed $func
+ * @param array $params
+ * @return array
+ */
+ public function calculate(&$model, $func, $params = array()) {
+ return array('count');
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/file_identifier.php b/code/ryzom/tools/server/www/webtt/app/models/file_identifier.php
new file mode 100644
index 000000000..885749702
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/file_identifier.php
@@ -0,0 +1,23 @@
+ array(
+ 'className' => 'ImportedTranslationFile',
+ 'foreignKey' => 'imported_translation_file_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ ),
+ 'Identifier' => array(
+ 'className' => 'Identifier',
+ 'foreignKey' => 'identifier_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ )
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/identifier.php b/code/ryzom/tools/server/www/webtt/app/models/identifier.php
new file mode 100644
index 000000000..a3e1246a2
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/identifier.php
@@ -0,0 +1,69 @@
+ array(
+ 'numeric' => array(
+ 'rule' => array('numeric'),
+ //'message' => 'Your custom message here',
+ //'allowEmpty' => false,
+ //'required' => false,
+ //'last' => false, // Stop validation after this rule
+ //'on' => 'create', // Limit validation to 'create' or 'update' operations
+ ),
+ ),
+ 'identifier' => array(
+ 'A_Za_z0_9' => array(
+ 'rule' => '/[A-Za-z0-9_@]+/',
+ 'message' => 'Identifier must consist only of the following caracteres: "A-Z", "a-z", "0-9", "@" and "_"',
+ //'allowEmpty' => false,
+ //'required' => false,
+ //'last' => false, // Stop validation after this rule
+ //'on' => 'create', // Limit validation to 'create' or 'update' operations
+ ),
+ ),
+ );
+ //The Associations below have been created with all possible keys, those that are not needed can be removed
+
+ var $belongsTo = array(
+ 'Language' => array(
+ 'className' => 'Language',
+ 'foreignKey' => 'language_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ )
+ );
+
+ var $hasMany = array(
+ 'Translation' => array(
+ 'className' => 'Translation',
+ 'foreignKey' => 'identifier_id',
+ 'dependent' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ ),
+ 'FileIdentifier' => array(
+ 'className' => 'FileIdentifier',
+ 'foreignKey' => 'identifier_id',
+ 'dependent' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ )
+ );
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/imported_translation_file.php b/code/ryzom/tools/server/www/webtt/app/models/imported_translation_file.php
new file mode 100644
index 000000000..c45bc435f
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/imported_translation_file.php
@@ -0,0 +1,46 @@
+ array(
+ 'className' => 'Language',
+ 'foreignKey' => 'language_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ )
+ );
+
+ var $hasMany = array(
+ 'FileIdentifier' => array(
+ 'className' => 'FileIdentifier',
+ 'foreignKey' => 'imported_translation_file_id',
+ 'dependent' => true,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ )
+ );
+
+ var $hasOne = array(
+ 'RawFile' => array(
+ 'className' => 'RawFile',
+ 'foreignKey' => 'filename',
+ 'dependand' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ ),
+ );
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/language.php b/code/ryzom/tools/server/www/webtt/app/models/language.php
new file mode 100644
index 000000000..eef16ce9e
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/language.php
@@ -0,0 +1,36 @@
+ array(
+ 'className' => 'Identifier',
+ 'foreignKey' => 'language_id',
+ 'dependent' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ ),
+ 'ImportedTranslationFile' => array(
+ 'className' => 'ImportedTranslationFile',
+ 'foreignKey' => 'language_id',
+ 'dependent' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ )
+ );
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/raw_file.php b/code/ryzom/tools/server/www/webtt/app/models/raw_file.php
new file mode 100644
index 000000000..cd77639e1
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/raw_file.php
@@ -0,0 +1,67 @@
+ array(
+ 'className' => 'ImportedTranslationFile',
+ 'foreignKey' => 'filename',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ ),
+ );
+/* var $hasOne = array(
+ 'FileIdentifier' => array(
+ 'className' => 'FileIdentifier',
+ 'foreignKey' => 'translation_file_id',
+ 'dependent' => true,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ )
+ );*/
+
+ public function open($dir, $filename)
+ {
+ $ds = $this->getDataSource();
+ $file = new File($filepath = $ds->config['path'] . DS . $dir . DS . $filename, false);
+ if (!$file)
+ return false;
+ if (!$file->readable())
+ return false;
+// var_dump($filename);
+ $this->_currentFile = $file;
+ return $file;
+ }
+
+ public function parseFile($file)
+ {
+ App::import("Vendor","UxtParser", array("file" => 'UxtParser.php'));
+ $parser = $this->_parser = new UxtParser();
+ if (!$this->_currentFile)
+ return false;
+ $entities = $parser->parseFile($this->_currentFile->read());
+ return $entities;
+ }
+ public function getLanguageCode($filename)
+ {
+// var_dump($filename);
+ if (preg_match('|^([a-z]{2})_diff_[A-F0-9]{8}\.uxt$|', $filename, $matches))
+ return $matches[1];
+ else if (preg_match('|^([a-z]{2})\.uxt$|', $filename, $matches))
+ return $matches[1];
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/translation.php b/code/ryzom/tools/server/www/webtt/app/models/translation.php
new file mode 100644
index 000000000..1a1859261
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/translation.php
@@ -0,0 +1,40 @@
+ array(
+ 'className' => 'Identifier',
+ 'foreignKey' => 'identifier_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ ),
+ 'User' => array(
+ 'className' => 'User',
+ 'foreignKey' => 'user_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ )
+ );
+
+ var $hasMany = array(
+ 'Vote' => array(
+ 'className' => 'Vote',
+ 'foreignKey' => 'translation_id',
+ 'dependent' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ )
+ );
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/user.php b/code/ryzom/tools/server/www/webtt/app/models/user.php
new file mode 100644
index 000000000..fe5157be9
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/user.php
@@ -0,0 +1,36 @@
+ array(
+ 'className' => 'Translation',
+ 'foreignKey' => 'user_id',
+ 'dependent' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ ),
+ 'Vote' => array(
+ 'className' => 'Vote',
+ 'foreignKey' => 'user_id',
+ 'dependent' => false,
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ )
+ );
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/models/vote.php b/code/ryzom/tools/server/www/webtt/app/models/vote.php
new file mode 100644
index 000000000..b3de691b0
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/models/vote.php
@@ -0,0 +1,23 @@
+ array(
+ 'className' => 'Translation',
+ 'foreignKey' => 'translation_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ ),
+ 'User' => array(
+ 'className' => 'User',
+ 'foreignKey' => 'user_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => ''
+ )
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/file_identifiers_controller.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/file_identifiers_controller.test.php
new file mode 100644
index 000000000..0c7298f47
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/file_identifiers_controller.test.php
@@ -0,0 +1,66 @@
+redirectUrl = $url;
+ }
+}
+
+class FileIdentifiersControllerTestCase extends CakeTestCase {
+ var $fixtures = array('app.file_identifier', 'app.translation_file', 'app.language', 'app.identifier', 'app.translation', 'app.user', 'app.vote');
+
+ function startTest() {
+ $this->FileIdentifiers =& new TestFileIdentifiersController();
+ $this->FileIdentifiers->constructClasses();
+ }
+
+ function endTest() {
+ unset($this->FileIdentifiers);
+ ClassRegistry::flush();
+ }
+
+ function testIndex() {
+
+ }
+
+ function testView() {
+
+ }
+
+ function testAdd() {
+
+ }
+
+ function testEdit() {
+
+ }
+
+ function testDelete() {
+
+ }
+
+ function testAdminIndex() {
+
+ }
+
+ function testAdminView() {
+
+ }
+
+ function testAdminAdd() {
+
+ }
+
+ function testAdminEdit() {
+
+ }
+
+ function testAdminDelete() {
+
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/identifiers_controller.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/identifiers_controller.test.php
new file mode 100644
index 000000000..72e3d7346
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/identifiers_controller.test.php
@@ -0,0 +1,66 @@
+redirectUrl = $url;
+ }
+}
+
+class IdentifiersControllerTestCase extends CakeTestCase {
+ var $fixtures = array('app.identifier', 'app.language', 'app.translation_file', 'app.file_identifier', 'app.translation', 'app.user', 'app.vote');
+
+ function startTest() {
+ $this->Identifiers =& new TestIdentifiersController();
+ $this->Identifiers->constructClasses();
+ }
+
+ function endTest() {
+ unset($this->Identifiers);
+ ClassRegistry::flush();
+ }
+
+ function testIndex() {
+
+ }
+
+ function testView() {
+
+ }
+
+ function testAdd() {
+
+ }
+
+ function testEdit() {
+
+ }
+
+ function testDelete() {
+
+ }
+
+ function testAdminIndex() {
+
+ }
+
+ function testAdminView() {
+
+ }
+
+ function testAdminAdd() {
+
+ }
+
+ function testAdminEdit() {
+
+ }
+
+ function testAdminDelete() {
+
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/languages_controller.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/languages_controller.test.php
new file mode 100644
index 000000000..1cc5063e8
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/languages_controller.test.php
@@ -0,0 +1,66 @@
+redirectUrl = $url;
+ }
+}
+
+class LanguagesControllerTestCase extends CakeTestCase {
+ var $fixtures = array('app.language', 'app.identifier', 'app.translation', 'app.user', 'app.vote', 'app.translation_file');
+
+ function startTest() {
+ $this->Languages =& new TestLanguagesController();
+ $this->Languages->constructClasses();
+ }
+
+ function endTest() {
+ unset($this->Languages);
+ ClassRegistry::flush();
+ }
+
+ function testIndex() {
+
+ }
+
+ function testView() {
+
+ }
+
+ function testAdd() {
+
+ }
+
+ function testEdit() {
+
+ }
+
+ function testDelete() {
+
+ }
+
+ function testAdminIndex() {
+
+ }
+
+ function testAdminView() {
+
+ }
+
+ function testAdminAdd() {
+
+ }
+
+ function testAdminEdit() {
+
+ }
+
+ function testAdminDelete() {
+
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/translation_files_controller.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/translation_files_controller.test.php
new file mode 100644
index 000000000..f60450a86
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/translation_files_controller.test.php
@@ -0,0 +1,26 @@
+redirectUrl = $url;
+ }
+}
+
+class TranslationFilesControllerTestCase extends CakeTestCase {
+ var $fixtures = array('app.translation_file', 'app.language', 'app.identifier', 'app.translation', 'app.user', 'app.vote');
+
+ function startTest() {
+ $this->TranslationFiles =& new TestTranslationFilesController();
+ $this->TranslationFiles->constructClasses();
+ }
+
+ function endTest() {
+ unset($this->TranslationFiles);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/translations_controller.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/translations_controller.test.php
new file mode 100644
index 000000000..aaeb1ec5a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/translations_controller.test.php
@@ -0,0 +1,66 @@
+redirectUrl = $url;
+ }
+}
+
+class TranslationsControllerTestCase extends CakeTestCase {
+ var $fixtures = array('app.translation', 'app.identifier', 'app.translation_file', 'app.language', 'app.user', 'app.vote');
+
+ function startTest() {
+ $this->Translations =& new TestTranslationsController();
+ $this->Translations->constructClasses();
+ }
+
+ function endTest() {
+ unset($this->Translations);
+ ClassRegistry::flush();
+ }
+
+ function testIndex() {
+
+ }
+
+ function testView() {
+
+ }
+
+ function testAdd() {
+
+ }
+
+ function testEdit() {
+
+ }
+
+ function testDelete() {
+
+ }
+
+ function testAdminIndex() {
+
+ }
+
+ function testAdminView() {
+
+ }
+
+ function testAdminAdd() {
+
+ }
+
+ function testAdminEdit() {
+
+ }
+
+ function testAdminDelete() {
+
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/users_controller.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/users_controller.test.php
new file mode 100644
index 000000000..3e9700388
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/users_controller.test.php
@@ -0,0 +1,66 @@
+redirectUrl = $url;
+ }
+}
+
+class UsersControllerTestCase extends CakeTestCase {
+ var $fixtures = array('app.user', 'app.translation', 'app.identifier', 'app.translation_file', 'app.language', 'app.vote');
+
+ function startTest() {
+ $this->Users =& new TestUsersController();
+ $this->Users->constructClasses();
+ }
+
+ function endTest() {
+ unset($this->Users);
+ ClassRegistry::flush();
+ }
+
+ function testIndex() {
+
+ }
+
+ function testView() {
+
+ }
+
+ function testAdd() {
+
+ }
+
+ function testEdit() {
+
+ }
+
+ function testDelete() {
+
+ }
+
+ function testAdminIndex() {
+
+ }
+
+ function testAdminView() {
+
+ }
+
+ function testAdminAdd() {
+
+ }
+
+ function testAdminEdit() {
+
+ }
+
+ function testAdminDelete() {
+
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/votes_controller.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/votes_controller.test.php
new file mode 100644
index 000000000..027661fb2
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/controllers/votes_controller.test.php
@@ -0,0 +1,66 @@
+redirectUrl = $url;
+ }
+}
+
+class VotesControllerTestCase extends CakeTestCase {
+ var $fixtures = array('app.vote', 'app.translation', 'app.identifier', 'app.translation_file', 'app.language', 'app.user');
+
+ function startTest() {
+ $this->Votes =& new TestVotesController();
+ $this->Votes->constructClasses();
+ }
+
+ function endTest() {
+ unset($this->Votes);
+ ClassRegistry::flush();
+ }
+
+ function testIndex() {
+
+ }
+
+ function testView() {
+
+ }
+
+ function testAdd() {
+
+ }
+
+ function testEdit() {
+
+ }
+
+ function testDelete() {
+
+ }
+
+ function testAdminIndex() {
+
+ }
+
+ function testAdminView() {
+
+ }
+
+ function testAdminAdd() {
+
+ }
+
+ function testAdminEdit() {
+
+ }
+
+ function testAdminDelete() {
+
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/models/file_identifier.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/file_identifier.test.php
new file mode 100644
index 000000000..0b6374de0
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/file_identifier.test.php
@@ -0,0 +1,17 @@
+FileIdentifier =& ClassRegistry::init('FileIdentifier');
+ }
+
+ function endTest() {
+ unset($this->FileIdentifier);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/models/identifier.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/identifier.test.php
new file mode 100644
index 000000000..45d94d4a8
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/identifier.test.php
@@ -0,0 +1,17 @@
+Identifier =& ClassRegistry::init('Identifier');
+ }
+
+ function endTest() {
+ unset($this->Identifier);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/models/language.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/language.test.php
new file mode 100644
index 000000000..e4d2251aa
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/language.test.php
@@ -0,0 +1,17 @@
+Language =& ClassRegistry::init('Language');
+ }
+
+ function endTest() {
+ unset($this->Language);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/models/translation.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/translation.test.php
new file mode 100644
index 000000000..534258df9
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/translation.test.php
@@ -0,0 +1,17 @@
+Translation =& ClassRegistry::init('Translation');
+ }
+
+ function endTest() {
+ unset($this->Translation);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/models/translation_file.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/translation_file.test.php
new file mode 100644
index 000000000..0ba6d97ee
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/translation_file.test.php
@@ -0,0 +1,17 @@
+TranslationFile =& ClassRegistry::init('TranslationFile');
+ }
+
+ function endTest() {
+ unset($this->TranslationFile);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/models/user.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/user.test.php
new file mode 100644
index 000000000..36660249d
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/user.test.php
@@ -0,0 +1,17 @@
+User =& ClassRegistry::init('User');
+ }
+
+ function endTest() {
+ unset($this->User);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/cases/models/vote.test.php b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/vote.test.php
new file mode 100644
index 000000000..0c42bc5ec
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/cases/models/vote.test.php
@@ -0,0 +1,17 @@
+Vote =& ClassRegistry::init('Vote');
+ }
+
+ function endTest() {
+ unset($this->Vote);
+ ClassRegistry::flush();
+ }
+
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/fixtures/file_identifier_fixture.php b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/file_identifier_fixture.php
new file mode 100644
index 000000000..6fca71e96
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/file_identifier_fixture.php
@@ -0,0 +1,31 @@
+ array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+ 'translation_file_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'command' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 50, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'translation_index' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'identifier_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'reference_string' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
+ );
+
+ var $records = array(
+ array(
+ 'id' => 1,
+ 'translation_file_id' => 1,
+ 'command' => 'Lorem ipsum dolor sit amet',
+ 'translation_index' => 1,
+ 'identifier_id' => 1,
+ 'reference_string' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
+ 'created' => '2011-05-31 16:07:59',
+ 'modified' => '2011-05-31 16:07:59'
+ ),
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/fixtures/identifier_fixture.php b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/identifier_fixture.php
new file mode 100644
index 000000000..156047ae6
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/identifier_fixture.php
@@ -0,0 +1,31 @@
+ array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+ 'translation_file_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'translation_index' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'identifier' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'reference_string' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'translated' => array('type' => 'boolean', 'null' => true, 'default' => '0'),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
+ );
+
+ var $records = array(
+ array(
+ 'id' => 1,
+ 'translation_file_id' => 1,
+ 'translation_index' => 1,
+ 'identifier' => 'Lorem ipsum dolor sit amet',
+ 'reference_string' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
+ 'translated' => 1,
+ 'created' => '2011-05-29 19:17:37',
+ 'modified' => '2011-05-29 19:17:37'
+ ),
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/fixtures/language_fixture.php b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/language_fixture.php
new file mode 100644
index 000000000..91fe7fb76
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/language_fixture.php
@@ -0,0 +1,25 @@
+ array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 50, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'code' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 10, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
+ );
+
+ var $records = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Lorem ipsum dolor sit amet',
+ 'code' => 'Lorem ip',
+ 'created' => '2011-05-31 15:48:42',
+ 'modified' => '2011-05-31 15:48:42'
+ ),
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/fixtures/translation_file_fixture.php b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/translation_file_fixture.php
new file mode 100644
index 000000000..4b9440ea4
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/translation_file_fixture.php
@@ -0,0 +1,25 @@
+ array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+ 'language_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'filename' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
+ );
+
+ var $records = array(
+ array(
+ 'id' => 1,
+ 'language_id' => 1,
+ 'filename' => 'Lorem ipsum dolor sit amet',
+ 'created' => '2011-05-29 19:13:14',
+ 'modified' => '2011-05-29 19:13:14'
+ ),
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/fixtures/translation_fixture.php b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/translation_fixture.php
new file mode 100644
index 000000000..fbe4bdaca
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/translation_fixture.php
@@ -0,0 +1,27 @@
+ array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+ 'identifier_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'translation_text' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'user_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
+ );
+
+ var $records = array(
+ array(
+ 'id' => 1,
+ 'identifier_id' => 1,
+ 'translation_text' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
+ 'user_id' => 1,
+ 'created' => '2011-05-29 19:19:41',
+ 'modified' => '2011-05-29 19:19:41'
+ ),
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/fixtures/user_fixture.php b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/user_fixture.php
new file mode 100644
index 000000000..5e0adfb2d
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/user_fixture.php
@@ -0,0 +1,23 @@
+ array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 100, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
+ );
+
+ var $records = array(
+ array(
+ 'id' => 1,
+ 'name' => 'Lorem ipsum dolor sit amet',
+ 'created' => '2011-05-29 19:20:07',
+ 'modified' => '2011-05-29 19:20:07'
+ ),
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tests/fixtures/vote_fixture.php b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/vote_fixture.php
new file mode 100644
index 000000000..cbe5389d6
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/tests/fixtures/vote_fixture.php
@@ -0,0 +1,25 @@
+ array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+ 'translation_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'user_id' => array('type' => 'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
+ );
+
+ var $records = array(
+ array(
+ 'id' => 1,
+ 'translation_id' => 1,
+ 'user_id' => 1,
+ 'created' => '2011-05-29 21:11:49',
+ 'modified' => '2011-05-29 21:11:49'
+ ),
+ );
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/tmp/cache/views/empty b/code/ryzom/tools/server/www/webtt/app/tmp/cache/views/empty
deleted file mode 100755
index e69de29bb..000000000
diff --git a/code/ryzom/tools/server/www/webtt/app/tmp/logs/empty b/code/ryzom/tools/server/www/webtt/app/tmp/logs/empty
deleted file mode 100755
index e69de29bb..000000000
diff --git a/code/ryzom/tools/server/www/webtt/app/tmp/sessions/empty b/code/ryzom/tools/server/www/webtt/app/tmp/sessions/empty
deleted file mode 100755
index e69de29bb..000000000
diff --git a/code/ryzom/tools/server/www/webtt/app/tmp/tests/empty b/code/ryzom/tools/server/www/webtt/app/tmp/tests/empty
deleted file mode 100755
index e69de29bb..000000000
diff --git a/code/ryzom/tools/server/www/webtt/app/vendors/UxtParser.php b/code/ryzom/tools/server/www/webtt/app/vendors/UxtParser.php
new file mode 100644
index 000000000..6d1855632
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/vendors/UxtParser.php
@@ -0,0 +1,180 @@
+################################\n";
+ var_dump($str);
+ var_dump($arr);
+ echo "\n";*/
+ return $arr;
+ }
+
+ function parseFile($file)
+ {
+ $parsedEnt = array();
+ $newEnt = false;
+ $entities = array();
+
+// $file = file_get_contents($this->pipeline_directory . $file);
+// var_dump(mb_substr($file, 0,3));
+// var_dump(substr($file, 0,3));
+// var_dump($file);
+ $file = $this->removeBOM($file);
+// var_dump($file);
+ $file = $this->removeComments($file);
+// var_dump($file);
+ $lines = explode("\n", $file);
+// echo "
################################\n";
+ foreach ($lines as $line)
+ {
+ $line = rtrim($line);
+ $parsedLine = $this->parseLine($line);
+
+ if (!$parsedLine)
+ continue;
+
+ if ($parsedLine["type"] == "index")
+ $parsedEnt["index"] = $parsedLine["index"];
+
+ if ($parsedLine["type"] == "string")
+ {
+/* echo "%%%% parsedEnt %%%%%\n";
+ var_dump($parsedEnt);
+
+ echo "%%%% parsedLine %%%%%\n";
+ var_dump($parsedLine);
+*/
+
+ if (!$parsedLine['identifier'])
+ {
+// echo "ZLACZENIE \n";
+ $parsedEnt['string'] .= "\n" . $parsedLine['string'];
+ }
+ else
+ {
+// echo "DODANIE \n";
+ $parsedEnt += $parsedLine;
+ }
+
+/* echo "%%%% parsedEnt after %%%%%\n";
+ var_dump($parsedEnt);*/
+ }
+
+ if ($parsedLine["type"] == "diff" && $parsedEnt)
+ {
+ $newEnt = true;
+ }
+
+ if ($newEnt)
+ {
+// var_dump($parsedEnt);
+ $entities[] = $parsedEnt;
+ $parsedEnt =array();
+ $newEnt = false;
+ }
+
+ if ($parsedLine["type"] == "diff")
+ {
+ $parsedEnt["diff"] = $parsedLine["command"];
+ $parsedEnt["index"] = $parsedLine["index"];
+ }
+ }
+ if ($parsedEnt)
+ $entities[] = $parsedEnt;
+/* var_dump($entities);
+ echo " \n";*/
+ return $entities;
+ }
+}
+?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/form.ctp b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/form.ctp
new file mode 100644
index 000000000..373f86fdc
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/form.ctp
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+ $data) {
+ foreach ($data as $alias => $details) {
+ echo "\n\t\t\t".Inflector::humanize($details['controller'])." ";
+ echo "\n\t\t\t\n";
+ }
+ }
+ ?>
+
+
+
+
+
+
";?>
+
+
+ Form->create('{$modelClass}');?>\n";?>
+
+ ";?>
+ Form->input('{$field}');\n";
+ }
+ }
+ if (!empty($associations['hasAndBelongsToMany'])) {
+ foreach ($associations['hasAndBelongsToMany'] as $assocName => $assocData) {
+ echo "\t\techo \$this->Form->input('{$assocName}');\n";
+ }
+ }
+ echo "\t?>\n";
+ ?>
+
+ Form->end(__('Submit', true));?>\n";
+ ?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/home.ctp b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/home.ctp
new file mode 100644
index 000000000..89e973e25
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/home.ctp
@@ -0,0 +1,89 @@
+
+
+Sweet, \"" . Inflector::humanize($app) . "\" got Baked by CakePHP!\n";
+$output .="
+ 0):
+ Debugger::checkSecurityKeys();
+endif;
+?>
+
+';
+ __('Your tmp directory is writable.');
+ echo '';
+ else:
+ echo '';
+ __('Your tmp directory is NOT writable.');
+ echo ' ';
+ endif;
+?>
+
+
+';
+ printf(__('The %s is being used for caching. To change the config edit APP/config/core.php ', true), ''. \$settings['engine'] . 'Engine ');
+ echo '';
+ else:
+ echo '';
+ __('Your cache is NOT working. Please check the settings in APP/config/core.php');
+ echo ' ';
+ endif;
+?>
+
+
+';
+ __('Your database configuration file is present.');
+ \$filePresent = true;
+ echo '';
+ else:
+ echo '';
+ __('Your database configuration file is NOT present.');
+ echo ' ';
+ __('Rename config/database.php.default to config/database.php');
+ echo ' ';
+ endif;
+?>
+
+getDataSource('default');
+?>
+
+isConnected()):
+ echo '';
+ __('Cake is able to connect to the database.');
+ echo ' ';
+ else:
+ echo '';
+ __('Cake is NOT able to connect to the database.');
+ echo ' ';
+ endif;
+?>
+
\n";
+$output .= "\n";
+$output .= "
\n";
+$output .= "
\n";
+$output .= "', APP . 'views' . DS . 'layouts' . DS . 'default.ctp. ', APP . 'webroot' . DS . 'css');\n";
+$output .= "?>\n";
+$output .= "
\n";
+?>
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/index.ctp b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/index.ctp
new file mode 100644
index 000000000..1a98eba2a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/index.ctp
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+ $data) {
+ foreach ($data as $alias => $details) {
+ echo "\n\t\t\t".Inflector::humanize($details['controller'])." ";
+ echo "\n\t\t\t\n";
+ }
+ }
+ ?>
+
+
+
+
+
+
";?>
+
+
+
+
+ tableHeaders(array(";
+
+ foreach($fields as $field) {
+ echo "\$paginator->sort('{$field}'),";
+ }
+ echo "__('Actions', true),";
+ echo "));\n";
+
+ echo "echo ''.\$tableHeaders.' '; ?>\n\n";
+
+ //// TABLE ROWS
+
+ echo "\n";
+ echo "\t>\n";
+ foreach ($fields as $field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $alias => $details) {
+ if ($field === $details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t\n\t\t\tHtml->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller' => '{$details['controller']}', 'action' => 'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>\n\t\t \n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t \n";
+ }
+ }
+
+ echo "\t\t\n";
+ echo "\t\t\tHtml->link(__('View', true), array('action' => 'view', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n";
+ echo "\t\t\tHtml->link(__('Edit', true), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n";
+ echo "\t\t\tHtml->link(__('Delete', true), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, sprintf(__('Are you sure you want to delete # %s?', true), \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n";
+ echo "\t\t \n";
+ echo "\t \n";
+
+ echo "\n";
+
+ //// TABLE FOOTER
+ echo "'.\$tableHeaders.''; ?>";
+ ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>";?>
+
+
+
+ Paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?>\n";?>
+ | Paginator->numbers();?>\n"?> |
+ Paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>\n";?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/view.ctp b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/view.ctp
new file mode 100644
index 000000000..fa7a17221
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/vendors/shells/templates/960grid/views/view.ctp
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+ $data) {
+ foreach ($data as $alias => $details) {
+ echo "\n\t\t\t".Inflector::humanize($details['controller'])." ";
+ echo "\n\t\t\t\n";
+ }
+ }
+ ?>
+
+
+
+
+
+
+
+
+
";?>
+
+
\n";?>
+ $details) {
+ if ($field === $details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t> \n";
+ echo "\t\t>\n\t\t\tHtml->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller' => '{$details['controller']}', 'action' => 'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>\n\t\t\t \n\t\t \n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t> \n";
+ echo "\t\t>\n\t\t\t\n\t\t\t \n\t\t \n";
+ }
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/elements/admin_left_menu.ctp b/code/ryzom/tools/server/www/webtt/app/views/elements/admin_left_menu.ctp
new file mode 100644
index 000000000..8cfaa41c4
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/elements/admin_left_menu.ctp
@@ -0,0 +1,28 @@
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/elements/main_menu.ctp b/code/ryzom/tools/server/www/webtt/app/views/elements/main_menu.ctp
new file mode 100644
index 000000000..7d6a70f97
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/elements/main_menu.ctp
@@ -0,0 +1,22 @@
+
+
+ Admin
+
+
+
+ Admin
+
+
+ Admin 2
+
+
+ Admin 3
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/add.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/add.ctp
new file mode 100644
index 000000000..fa9470120
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/add.ctp
@@ -0,0 +1,25 @@
+
+Form->create('FileIdentifier');?>
+
+
+ Form->input('translation_file_id');
+ echo $this->Form->input('command');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier_id');
+ echo $this->Form->input('reference_string');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List File Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_add.ctp
new file mode 100644
index 000000000..4f3898be9
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_add.ctp
@@ -0,0 +1,25 @@
+
+Form->create('FileIdentifier');?>
+
+
+ Form->input('translation_file_id');
+ echo $this->Form->input('command');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier_id');
+ echo $this->Form->input('reference_string');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List File Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_edit.ctp
new file mode 100644
index 000000000..9a6609be7
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_edit.ctp
@@ -0,0 +1,27 @@
+
+Form->create('FileIdentifier');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('translation_file_id');
+ echo $this->Form->input('command');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier_id');
+ echo $this->Form->input('reference_string');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('FileIdentifier.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('FileIdentifier.id'))); ?>
+ Html->link(__('List File Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_index.ctp
new file mode 100644
index 000000000..c62d5dc8e
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_index.ctp
@@ -0,0 +1,67 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('translation_file_id');?>
+ Paginator->sort('command');?>
+ Paginator->sort('translation_index');?>
+ Paginator->sort('identifier_id');?>
+ Paginator->sort('reference_string');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($fileIdentifier['TranslationFile']['filename'], array('controller' => 'translation_files', 'action' => 'view', $fileIdentifier['TranslationFile']['id'])); ?>
+
+
+
+
+ Html->link($fileIdentifier['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $fileIdentifier['Identifier']['id'])); ?>
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $fileIdentifier['FileIdentifier']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $fileIdentifier['FileIdentifier']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New File Identifier', true), array('action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_view.ctp
new file mode 100644
index 000000000..8f375c882
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/admin_view.ctp
@@ -0,0 +1,58 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($fileIdentifier['TranslationFile']['filename'], array('controller' => 'translation_files', 'action' => 'view', $fileIdentifier['TranslationFile']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($fileIdentifier['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $fileIdentifier['Identifier']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit File Identifier', true), array('action' => 'edit', $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('Delete File Identifier', true), array('action' => 'delete', $fileIdentifier['FileIdentifier']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('List File Identifiers', true), array('action' => 'index')); ?>
+ Html->link(__('New File Identifier', true), array('action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/edit.ctp
new file mode 100644
index 000000000..d85d2e100
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/edit.ctp
@@ -0,0 +1,27 @@
+
+Form->create('FileIdentifier');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('translation_file_id');
+ echo $this->Form->input('command');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier_id');
+ echo $this->Form->input('reference_string');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('FileIdentifier.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('FileIdentifier.id'))); ?>
+ Html->link(__('List File Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/index.ctp
new file mode 100644
index 000000000..c62d5dc8e
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/index.ctp
@@ -0,0 +1,67 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('translation_file_id');?>
+ Paginator->sort('command');?>
+ Paginator->sort('translation_index');?>
+ Paginator->sort('identifier_id');?>
+ Paginator->sort('reference_string');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($fileIdentifier['TranslationFile']['filename'], array('controller' => 'translation_files', 'action' => 'view', $fileIdentifier['TranslationFile']['id'])); ?>
+
+
+
+
+ Html->link($fileIdentifier['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $fileIdentifier['Identifier']['id'])); ?>
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $fileIdentifier['FileIdentifier']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $fileIdentifier['FileIdentifier']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New File Identifier', true), array('action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/view.ctp
new file mode 100644
index 000000000..8f375c882
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/file_identifiers/view.ctp
@@ -0,0 +1,58 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($fileIdentifier['TranslationFile']['filename'], array('controller' => 'translation_files', 'action' => 'view', $fileIdentifier['TranslationFile']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($fileIdentifier['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $fileIdentifier['Identifier']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit File Identifier', true), array('action' => 'edit', $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('Delete File Identifier', true), array('action' => 'delete', $fileIdentifier['FileIdentifier']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $fileIdentifier['FileIdentifier']['id'])); ?>
+ Html->link(__('List File Identifiers', true), array('action' => 'index')); ?>
+ Html->link(__('New File Identifier', true), array('action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/add.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/add.ctp
new file mode 100644
index 000000000..0ac7bb80b
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/add.ctp
@@ -0,0 +1,25 @@
+
+Form->create('Identifier');?>
+
+
+ Form->input('language_id');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier');
+ echo $this->Form->input('reference_string');
+ echo $this->Form->input('translated');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_add.ctp
new file mode 100644
index 000000000..41b9cf94b
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_add.ctp
@@ -0,0 +1,25 @@
+
+Form->create('Identifier');?>
+
+
+ Form->input('language_id');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier');
+ echo $this->Form->input('reference_string');
+ echo $this->Form->input('translated');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_edit.ctp
new file mode 100644
index 000000000..ab749fd75
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_edit.ctp
@@ -0,0 +1,27 @@
+
+Form->create('Identifier');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('language_id');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier');
+ echo $this->Form->input('reference_string');
+ echo $this->Form->input('translated');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Identifier.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Identifier.id'))); ?>
+ Html->link(__('List Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_index.ctp
new file mode 100644
index 000000000..7f5a60a26
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_index.ctp
@@ -0,0 +1,65 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('language_id');?>
+ Paginator->sort('translation_index');?>
+ Paginator->sort('identifier');?>
+ Paginator->sort('reference_string');?>
+ Paginator->sort('translated');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($identifier['Language']['name'], array('controller' => 'languages', 'action' => 'view', $identifier['Language']['id'])); ?>
+
+
+
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $identifier['Identifier']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $identifier['Identifier']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $identifier['Identifier']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $identifier['Identifier']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New Identifier', true), array('action' => 'add')); ?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_view.ctp
new file mode 100644
index 000000000..a75ccf2ca
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/admin_view.ctp
@@ -0,0 +1,152 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($identifier['Language']['name'], array('controller' => 'languages', 'action' => 'view', $identifier['Language']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Identifier', true), array('action' => 'edit', $identifier['Identifier']['id'])); ?>
+ Html->link(__('Delete Identifier', true), array('action' => 'delete', $identifier['Identifier']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $identifier['Identifier']['id'])); ?>
+ Html->link(__('List Identifiers', true), array('action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('action' => 'add')); ?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+ Html->link(__('New File Identifier', true), array('controller' => 'file_identifiers', 'action' => 'add')); ?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/edit.ctp
new file mode 100644
index 000000000..9b069eb7b
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/edit.ctp
@@ -0,0 +1,27 @@
+
+Form->create('Identifier');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('language_id');
+ echo $this->Form->input('translation_index');
+ echo $this->Form->input('identifier');
+ echo $this->Form->input('reference_string');
+ echo $this->Form->input('translated');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Identifier.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Identifier.id'))); ?>
+ Html->link(__('List Identifiers', true), array('action' => 'index'));?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/index.ctp
new file mode 100644
index 000000000..254f72b4e
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/index.ctp
@@ -0,0 +1,62 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('language_id');?>
+ Paginator->sort('translation_index');?>
+ Paginator->sort('identifier');?>
+ Paginator->sort('reference_string');?>
+ Paginator->sort('translated');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($identifier['Language']['name'], array('controller' => 'languages', 'action' => 'view', $identifier['Language']['id'])); ?>
+
+
+
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $identifier['Identifier']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/identifiers/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/identifiers/view.ctp
new file mode 100644
index 000000000..7539a2e33
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/identifiers/view.ctp
@@ -0,0 +1,141 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($identifier['Language']['name'], array('controller' => 'languages', 'action' => 'view', $identifier['Language']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('List Identifiers', true), array('action' => 'index')); ?>
+
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_add.ctp
new file mode 100644
index 000000000..b87a6fdd6
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_add.ctp
@@ -0,0 +1,22 @@
+
+Form->create('TranslationFile');?>
+
+
+ Form->input('language_id');
+ echo $this->Form->input('filename');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Translation Files', true), array('action' => 'index'));?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+ Html->link(__('New File Identifier', true), array('controller' => 'file_identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_edit.ctp
new file mode 100644
index 000000000..d5691f4bb
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_edit.ctp
@@ -0,0 +1,24 @@
+
+Form->create('TranslationFile');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('language_id');
+ echo $this->Form->input('filename');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('TranslationFile.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('TranslationFile.id'))); ?>
+ Html->link(__('List Translation Files', true), array('action' => 'index'));?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+ Html->link(__('New File Identifier', true), array('controller' => 'file_identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_index.ctp
new file mode 100644
index 000000000..390d6132e
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_index.ctp
@@ -0,0 +1,59 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('language_id');?>
+ Paginator->sort('filename');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($importedTranslationFile['Language']['name'], array('controller' => 'languages', 'action' => 'view', $importedTranslationFile['Language']['id'])); ?>
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $importedTranslationFile['ImportedTranslationFile']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $importedTranslationFile['ImportedTranslationFile']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $importedTranslationFile['ImportedTranslationFile']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $importedTranslationFile['ImportedTranslationFile']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New Translation File', true), array('action' => 'add')); ?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+ Html->link(__('New File Identifier', true), array('controller' => 'file_identifiers', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_view.ctp
new file mode 100644
index 000000000..6e9496ba1
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/admin_view.ctp
@@ -0,0 +1,91 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($translationFile['Language']['name'], array('controller' => 'languages', 'action' => 'view', $translationFile['Language']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Translation File', true), array('action' => 'edit', $translationFile['TranslationFile']['id'])); ?>
+ Html->link(__('Delete Translation File', true), array('action' => 'delete', $translationFile['TranslationFile']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $translationFile['TranslationFile']['id'])); ?>
+ Html->link(__('List Translation Files', true), array('action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('action' => 'add')); ?>
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+ Html->link(__('New Language', true), array('controller' => 'languages', 'action' => 'add')); ?>
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+ Html->link(__('New File Identifier', true), array('controller' => 'file_identifiers', 'action' => 'add')); ?>
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/index.ctp
new file mode 100644
index 000000000..a04448484
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/index.ctp
@@ -0,0 +1,55 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('language_id');?>
+ Paginator->sort('filename');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($importedTranslationFile['Language']['name'], array('controller' => 'languages', 'action' => 'view', $importedTranslationFile['Language']['id'])); ?>
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $importedTranslationFile['ImportedTranslationFile']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/view.ctp
new file mode 100644
index 000000000..833367868
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/imported_translation_files/view.ctp
@@ -0,0 +1,122 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($importedTranslationFile['Language']['name'], array('controller' => 'languages', 'action' => 'view', $importedTranslationFile['Language']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('List Translation Files', true), array('action' => 'index')); ?>
+
+ Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+
+ Html->link(__('List File Identifiers', true), array('controller' => 'file_identifiers', 'action' => 'index')); ?>
+
+
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/add.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/add.ctp
new file mode 100644
index 000000000..23eed9eb2
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/add.ctp
@@ -0,0 +1,22 @@
+
+Form->create('Language');?>
+
+
+ Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Languages', true), array('action' => 'index'));?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_add.ctp
new file mode 100644
index 000000000..d4e5e1034
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_add.ctp
@@ -0,0 +1,22 @@
+
+Form->create('Language');?>
+
+
+ Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Languages', true), array('action' => 'index'));?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_edit.ctp
new file mode 100644
index 000000000..f68d48baa
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_edit.ctp
@@ -0,0 +1,24 @@
+
+Form->create('Language');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Language.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Language.id'))); ?>
+ Html->link(__('List Languages', true), array('action' => 'index'));?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_index.ctp
new file mode 100644
index 000000000..e18bb771c
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_index.ctp
@@ -0,0 +1,57 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('name');?>
+ Paginator->sort('code');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $language['Language']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $language['Language']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $language['Language']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $language['Language']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New Language', true), array('action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_view.ctp
new file mode 100644
index 000000000..aa7f2c923
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/admin_view.ctp
@@ -0,0 +1,133 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Language', true), array('action' => 'edit', $language['Language']['id'])); ?>
+ Html->link(__('Delete Language', true), array('action' => 'delete', $language['Language']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $language['Language']['id'])); ?>
+ Html->link(__('List Languages', true), array('action' => 'index')); ?>
+ Html->link(__('New Language', true), array('action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/edit.ctp
new file mode 100644
index 000000000..5eab47bb4
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/edit.ctp
@@ -0,0 +1,24 @@
+
+Form->create('Language');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Language.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Language.id'))); ?>
+ Html->link(__('List Languages', true), array('action' => 'index'));?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+ Html->link(__('New Translation File', true), array('controller' => 'translation_files', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/index.ctp
new file mode 100644
index 000000000..64cdf3bb4
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/index.ctp
@@ -0,0 +1,53 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('name');?>
+ Paginator->sort('code');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $language['Language']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages.bak/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/view.ctp
new file mode 100644
index 000000000..8560bc864
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages.bak/view.ctp
@@ -0,0 +1,114 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('List Languages', true), array('action' => 'index')); ?>
+
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+
+ Html->link(__('List Translation Files', true), array('controller' => 'translation_files', 'action' => 'index')); ?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/add.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/add.ctp
new file mode 100644
index 000000000..d839e5c26
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/add.ctp
@@ -0,0 +1,43 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+ Form->create('Language');?>
+
+
+ Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+ Form->end(__('Submit', true));?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_add.ctp
new file mode 100644
index 000000000..5304881f2
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_add.ctp
@@ -0,0 +1,43 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+ Form->create('Language');?>
+
+
+ Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+ Form->end(__('Submit', true));?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_edit.ctp
new file mode 100644
index 000000000..3888cb2f2
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_edit.ctp
@@ -0,0 +1,45 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+ Form->create('Language');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+ Form->end(__('Submit', true));?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_index.ctp
new file mode 100644
index 000000000..270a5b1f0
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_index.ctp
@@ -0,0 +1,74 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+
+ tableHeaders(array($paginator->sort('id'),$paginator->sort('name'),$paginator->sort('code'),$paginator->sort('created'),$paginator->sort('modified'),__('Actions', true),));
+echo ''.$tableHeaders.' '; ?>
+
+
+ >
+
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $language['Language']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $language['Language']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $language['Language']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $language['Language']['id'])); ?>
+
+
+
+'.$tableHeaders.''; ?>
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_view.ctp
new file mode 100644
index 000000000..202516a06
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/admin_view.ctp
@@ -0,0 +1,172 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/edit.ctp
new file mode 100644
index 000000000..ce5d275fb
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/edit.ctp
@@ -0,0 +1,45 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+ Form->create('Language');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('name');
+ echo $this->Form->input('code');
+ ?>
+
+ Form->end(__('Submit', true));?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/index.ctp
new file mode 100644
index 000000000..270a5b1f0
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/index.ctp
@@ -0,0 +1,74 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+
+ tableHeaders(array($paginator->sort('id'),$paginator->sort('name'),$paginator->sort('code'),$paginator->sort('created'),$paginator->sort('modified'),__('Actions', true),));
+echo ''.$tableHeaders.' '; ?>
+
+
+ >
+
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $language['Language']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $language['Language']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $language['Language']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $language['Language']['id'])); ?>
+
+
+
+'.$tableHeaders.''; ?>
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/languages/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/languages/view.ctp
new file mode 100644
index 000000000..92ed15f28
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/languages/view.ctp
@@ -0,0 +1,172 @@
+
+
+
+
+
Languages
+
+
+ Identifiers
+
+
+ Translation Files
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/layouts/admin.ctp b/code/ryzom/tools/server/www/webtt/app/views/layouts/admin.ctp
new file mode 100644
index 000000000..68fba719a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/layouts/admin.ctp
@@ -0,0 +1,41 @@
+
+
+
+ Html->charset(); ?>
+
+ -
+
+
+ Html->meta('icon');
+ //echo $this->Html->css('cake.generic');
+ echo $this->Html->css(array('reset', 'text', 'grid', 'layout', 'nav'));
+ echo '';
+ echo '';
+ echo $this->Html->script(array('jquery-1.3.2.min.js', 'jquery-ui.js', 'jquery-fluid16.js'));
+ echo $scripts_for_layout;
+ ?>
+
+
+
+
+
+
+ element('admin/main_menu'); ?>
+
+
+
+
+ Session->flash(); ?>
+
+
+
+
+
+ element('sql_dump'); ?>
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/layouts/default.ctp b/code/ryzom/tools/server/www/webtt/app/views/layouts/default.ctp
new file mode 100644
index 000000000..083a2a64c
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/layouts/default.ctp
@@ -0,0 +1,59 @@
+
+
+
+
+ Html->charset(); ?>
+
+
+
+
+ Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $scripts_for_layout;
+ ?>
+
+
+
+
+
+
+ Session->flash(); ?>
+
+
+
+
+
+
+ element('sql_dump'); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/layouts/default.ctp.bak b/code/ryzom/tools/server/www/webtt/app/views/layouts/default.ctp.bak
new file mode 100644
index 000000000..ee4c977be
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/layouts/default.ctp.bak
@@ -0,0 +1,59 @@
+
+
+
+
+ Html->charset(); ?>
+
+
+
+
+ Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $scripts_for_layout;
+ ?>
+
+
+
+
+
+
+ Session->flash(); ?>
+
+
+
+
+
+
+ element('sql_dump'); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/layouts/default_debug.ctp b/code/ryzom/tools/server/www/webtt/app/views/layouts/default_debug.ctp
new file mode 100644
index 000000000..5e06ca479
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/layouts/default_debug.ctp
@@ -0,0 +1,59 @@
+
+
+
+
+ Html->charset(); ?>
+
+
+
+
+ Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $scripts_for_layout;
+ ?>
+
+
+
+
+
+
+ Session->flash(); ?>
+
+
+
+
+
+
+ element('sql_dump'); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/layouts/new.ctp b/code/ryzom/tools/server/www/webtt/app/views/layouts/new.ctp
new file mode 100644
index 000000000..ccc9a96d4
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/layouts/new.ctp
@@ -0,0 +1,38 @@
+
+
+
+ Html->charset(); ?>
+
+ Html->meta('icon');
+ //echo $this->Html->css('cake.generic');
+ echo $this->Html->css(array('reset', 'text', 'grid', 'layout', 'nav'));
+ echo '';
+ echo '';
+ echo $this->Html->script(array('jquery-1.3.2.min.js', 'jquery-ui.js', 'jquery-fluid16.js'));
+ echo $scripts_for_layout;
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+ Session->flash(); ?>
+
+
+
+
+
+ element('sql_dump'); ?>
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/pages/home.ctp b/code/ryzom/tools/server/www/webtt/app/views/pages/home.ctp
new file mode 100644
index 000000000..631b9f62c
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/pages/home.ctp
@@ -0,0 +1,23 @@
+
+
+
+Html->link(__('List Languages', true), array('controller' => 'languages', 'action' => 'index')); ?>
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/raw_files/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/raw_files/admin_index.ctp
new file mode 120000
index 000000000..f5532221a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/raw_files/admin_index.ctp
@@ -0,0 +1 @@
+index.ctp
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/raw_files/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/raw_files/index.ctp
new file mode 100644
index 000000000..4b0b8baef
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/raw_files/index.ctp
@@ -0,0 +1,52 @@
+
+
+
+
+ Paginator->sort('filename');?>
+ Paginator->sort('size');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Time->nice($object['RawFile']['modified']); ?>
+
+ Html->link(__('View', true), array('action' => 'view', $object['RawFile']['filename'])); ?>
+ Html->link(__('Import', true), array('action' => 'import', $object['RawFile']['filename'])); ?>
+ Html->link(__('Export', true), array('action' => 'export', $object['RawFile']['filename']), null, sprintf(__('Are you sure you want to export # %s?', true), $object['RawFile']['filename'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('List Raw Files', true), array('controller' => 'raw_files', 'action' => 'index')); ?>
+
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/raw_files/listdir.ctp b/code/ryzom/tools/server/www/webtt/app/views/raw_files/listdir.ctp
new file mode 120000
index 000000000..f5532221a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/raw_files/listdir.ctp
@@ -0,0 +1 @@
+index.ctp
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/raw_files/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/raw_files/view.ctp
new file mode 100644
index 000000000..ee5e7e265
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/raw_files/view.ctp
@@ -0,0 +1,43 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($vote['Translation']['translation_text'], array('controller' => 'translations', 'action' => 'view', $vote['Translation']['id'])); ?>
+
+
+ >
+ >
+ Html->link($vote['User']['name'], array('controller' => 'users', 'action' => 'view', $vote['User']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Vote', true), array('action' => 'edit', $vote['Vote']['id'])); ?>
+ Html->link(__('Delete Vote', true), array('action' => 'delete', $vote['Vote']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $vote['Vote']['id'])); ?>
+ Html->link(__('List Votes', true), array('action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/scaffolds/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/scaffolds/edit.ctp
new file mode 100644
index 000000000..34b570631
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/scaffolds/edit.ctp
@@ -0,0 +1,47 @@
+
+
+Form->create();
+ echo $this->Form->inputs($scaffoldFields, array('created', 'modified', 'updated'));
+ echo $this->Form->end(__('Submit', true));
+?>
+
+
+
+
+action != 'add'):?>
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value($modelClass.'.'.$primaryKey)), null, __('Are you sure you want to delete', true).' #' . $this->Form->value($modelClass.'.'.$primaryKey)); ?>
+
+ Html->link(__('List', true).' '.$pluralHumanName, array('action' => 'index'));?>
+ $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "\t\t" . $this->Html->link(sprintf(__('List %s', true), Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' =>'index')) . " \n";
+ echo "\t\t" . $this->Html->link(sprintf(__('New %s', true), Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' =>'add')) . " \n";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/scaffolds/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/scaffolds/index.ctp
new file mode 100644
index 000000000..ce4a09a3d
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/scaffolds/index.ctp
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+ Paginator->sort($_field);?>
+
+
+
+\n";
+ foreach ($scaffoldFields as $_field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $_alias => $_details) {
+ if ($_field === $_details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t\n\t\t\t" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "\n\t\t \n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t\n\t\t\t" . ${$singularVar}[$modelClass][$_field] . " \n\t\t \n";
+ }
+ }
+
+ echo "\t\t\n";
+ echo "\t\t\t" . $this->Html->link(__('View', true), array('action' => 'view', ${$singularVar}[$modelClass][$primaryKey])) . "\n";
+ echo "\t\t\t" . $this->Html->link(__('Edit', true), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey])) . "\n";
+ echo "\t\t\t" . $this->Html->link(__('Delete', true), array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]), null, __('Are you sure you want to delete', true).' #' . ${$singularVar}[$modelClass][$primaryKey]) . "\n";
+ echo "\t\t \n";
+ echo "\t\n";
+
+endforeach;
+echo "\n";
+?>
+
+
Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class' => 'disabled')) . "\n";?>
+ | Paginator->numbers() . "\n"?>
+ Paginator->next(__('next', true) .' >>', array(), null, array('class' => 'disabled')) . "\n";?>
+
+
+
+
+
+ Html->link(sprintf(__('New %s', true), $singularHumanName), array('action' => 'add')); ?>
+ $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "\t\t" . $this->Html->link(sprintf(__('List %s', true), Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . " \n";
+ echo "\t\t" . $this->Html->link(sprintf(__('New %s', true), Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . " \n";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/scaffolds/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/scaffolds/view.ctp
new file mode 100644
index 000000000..ae898d1fa
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/scaffolds/view.ctp
@@ -0,0 +1,161 @@
+
+
+
+
+ $_details) {
+ if ($_field === $_details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t" . Inflector::humanize($_alias) . " \n";
+ echo "\t\t\n\t\t\t" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "\n\t\t \n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t" . Inflector::humanize($_field) . " \n";
+ echo "\t\t\n\t\t\t{${$singularVar}[$modelClass][$_field]}\n \t\t \n";
+ }
+}
+?>
+
+
+
+
+
+" .$this->Html->link(sprintf(__('Edit %s', true), $singularHumanName), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey])). " \n";
+ echo "\t\t" .$this->Html->link(sprintf(__('Delete %s', true), $singularHumanName), array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]), null, __('Are you sure you want to delete', true).' #' . ${$singularVar}[$modelClass][$primaryKey] . '?'). " \n";
+ echo "\t\t" .$this->Html->link(sprintf(__('List %s', true), $pluralHumanName), array('action' => 'index')). " \n";
+ echo "\t\t" .$this->Html->link(sprintf(__('New %s', true), $singularHumanName), array('action' => 'add')). " \n";
+
+ $done = array();
+ foreach ($associations as $_type => $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "\t\t" . $this->Html->link(sprintf(__('List %s', true), Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . " \n";
+ echo "\t\t" . $this->Html->link(sprintf(__('New %s', true), Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . " \n";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+
+
+ $_details): ?>
+
+ $_details):
+$otherSingularVar = Inflector::variable($_alias);
+?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/add.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/add.ctp
new file mode 100644
index 000000000..eaa529564
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/add.ctp
@@ -0,0 +1,25 @@
+
+Form->create('Translation');?>
+
+
+ Form->input('identifier_id');
+ echo $this->Form->input('translation_text');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Translations', true), array('action' => 'index'));?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_add.ctp
new file mode 100644
index 000000000..0313500b5
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_add.ctp
@@ -0,0 +1,25 @@
+
+Form->create('Translation');?>
+
+
+ Form->input('identifier_id');
+ echo $this->Form->input('translation_text');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Translations', true), array('action' => 'index'));?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_edit.ctp
new file mode 100644
index 000000000..7387d0c59
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_edit.ctp
@@ -0,0 +1,27 @@
+
+Form->create('Translation');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('identifier_id');
+ echo $this->Form->input('translation_text');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Translation.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Translation.id'))); ?>
+ Html->link(__('List Translations', true), array('action' => 'index'));?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_index.ctp
new file mode 100644
index 000000000..1a377991c
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_index.ctp
@@ -0,0 +1,68 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('identifier_id');?>
+ Paginator->sort('translation_text');?>
+ Paginator->sort('user_id');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($translation['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $translation['Identifier']['id'])); ?>
+
+
+
+ Html->link($translation['User']['name'], array('controller' => 'users', 'action' => 'view', $translation['User']['id'])); ?>
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $translation['Translation']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $translation['Translation']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $translation['Translation']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $translation['Translation']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New Translation', true), array('action' => 'add')); ?>
+
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_view.ctp
new file mode 100644
index 000000000..c21a808ab
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/admin_view.ctp
@@ -0,0 +1,92 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($translation['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $translation['Identifier']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($translation['User']['name'], array('controller' => 'users', 'action' => 'view', $translation['User']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Translation', true), array('action' => 'edit', $translation['Translation']['id'])); ?>
+ Html->link(__('Delete Translation', true), array('action' => 'delete', $translation['Translation']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $translation['Translation']['id'])); ?>
+ Html->link(__('List Translations', true), array('action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('action' => 'add')); ?>
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+ Html->link(__('New Identifier', true), array('controller' => 'identifiers', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/edit.ctp
new file mode 100644
index 000000000..0f84bd4bf
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/edit.ctp
@@ -0,0 +1,28 @@
+
+Form->create('Translation');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('identifier_id');
+ echo $this->Form->input('translation_text');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Translation.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Translation.id'))); ?>
+
+ Html->link(__('List Translations', true), array('action' => 'index'));?>
+
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/index.ctp
new file mode 100644
index 000000000..2bf80c563
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/index.ctp
@@ -0,0 +1,63 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('identifier_id');?>
+ Paginator->sort('translation_text');?>
+ Paginator->sort('user_id');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($translation['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $translation['Identifier']['id'])); ?>
+
+
+
+ Html->link($translation['User']['name'], array('controller' => 'users', 'action' => 'view', $translation['User']['id'])); ?>
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $translation['Translation']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New Translation', true), array('action' => 'add')); ?>
+
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/translations/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/translations/view.ctp
new file mode 100644
index 000000000..06302a251
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/translations/view.ctp
@@ -0,0 +1,91 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($translation['Identifier']['identifier'], array('controller' => 'identifiers', 'action' => 'view', $translation['Identifier']['id'])); ?>
+ []
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($translation['User']['name'], array('controller' => 'users', 'action' => 'view', $translation['User']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Translation', true), array('action' => 'edit', $translation['Translation']['id'])); ?>
+ Html->link(__('List Translations', true), array('action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('action' => 'add')); ?>
+
+ Html->link(__('List Identifiers', true), array('controller' => 'identifiers', 'action' => 'index')); ?>
+
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/add.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/add.ctp
new file mode 100644
index 000000000..0fbe8bb8d
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/add.ctp
@@ -0,0 +1,21 @@
+
+Form->create('User');?>
+
+
+ Form->input('name');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Users', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/admin_add.ctp
new file mode 100644
index 000000000..8272a80e3
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/admin_add.ctp
@@ -0,0 +1,21 @@
+
+Form->create('User');?>
+
+
+ Form->input('name');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Users', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/admin_edit.ctp
new file mode 100644
index 000000000..276341ea1
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/admin_edit.ctp
@@ -0,0 +1,23 @@
+
+Form->create('User');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('name');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('User.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('User.id'))); ?>
+ Html->link(__('List Users', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/admin_index.ctp
new file mode 100644
index 000000000..b517108b3
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/admin_index.ctp
@@ -0,0 +1,57 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('name');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $user['User']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $user['User']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $user['User']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $user['User']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New User', true), array('action' => 'add')); ?>
+
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/admin_view.ctp
new file mode 100644
index 000000000..d43038c55
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/admin_view.ctp
@@ -0,0 +1,124 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit User', true), array('action' => 'edit', $user['User']['id'])); ?>
+ Html->link(__('Delete User', true), array('action' => 'delete', $user['User']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $user['User']['id'])); ?>
+ Html->link(__('List Users', true), array('action' => 'index')); ?>
+ Html->link(__('New User', true), array('action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/edit.ctp
new file mode 100644
index 000000000..fb3782453
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/edit.ctp
@@ -0,0 +1,23 @@
+
+Form->create('User');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('name');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('User.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('User.id'))); ?>
+ Html->link(__('List Users', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/index.ctp
new file mode 100644
index 000000000..b517108b3
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/index.ctp
@@ -0,0 +1,57 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('name');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $user['User']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $user['User']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $user['User']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $user['User']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New User', true), array('action' => 'add')); ?>
+
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/users/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/users/view.ctp
new file mode 100644
index 000000000..d43038c55
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/users/view.ctp
@@ -0,0 +1,124 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit User', true), array('action' => 'edit', $user['User']['id'])); ?>
+ Html->link(__('Delete User', true), array('action' => 'delete', $user['User']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $user['User']['id'])); ?>
+ Html->link(__('List Users', true), array('action' => 'index')); ?>
+ Html->link(__('New User', true), array('action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Votes', true), array('controller' => 'votes', 'action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('controller' => 'votes', 'action' => 'add')); ?>
+
+
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/add.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/add.ctp
new file mode 100644
index 000000000..1c548858e
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/add.ctp
@@ -0,0 +1,22 @@
+
+Form->create('Vote');?>
+
+
+ Form->input('translation_id');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Votes', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/admin_add.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_add.ctp
new file mode 100644
index 000000000..64b8b7b0f
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_add.ctp
@@ -0,0 +1,22 @@
+
+Form->create('Vote');?>
+
+
+ Form->input('translation_id');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('List Votes', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/admin_edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_edit.ctp
new file mode 100644
index 000000000..bfddacefb
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_edit.ctp
@@ -0,0 +1,24 @@
+
+Form->create('Vote');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('translation_id');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Vote.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Vote.id'))); ?>
+ Html->link(__('List Votes', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/admin_index.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_index.ctp
new file mode 100644
index 000000000..ec5ae6db7
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_index.ctp
@@ -0,0 +1,63 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('translation_id');?>
+ Paginator->sort('user_id');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($vote['Translation']['translation_text'], array('controller' => 'translations', 'action' => 'view', $vote['Translation']['id'])); ?>
+
+
+ Html->link($vote['User']['name'], array('controller' => 'users', 'action' => 'view', $vote['User']['id'])); ?>
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $vote['Vote']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $vote['Vote']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $vote['Vote']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $vote['Vote']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New Vote', true), array('action' => 'add')); ?>
+
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/admin_view.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_view.ctp
new file mode 100644
index 000000000..ee5e7e265
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/admin_view.ctp
@@ -0,0 +1,43 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($vote['Translation']['translation_text'], array('controller' => 'translations', 'action' => 'view', $vote['Translation']['id'])); ?>
+
+
+ >
+ >
+ Html->link($vote['User']['name'], array('controller' => 'users', 'action' => 'view', $vote['User']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Vote', true), array('action' => 'edit', $vote['Vote']['id'])); ?>
+ Html->link(__('Delete Vote', true), array('action' => 'delete', $vote['Vote']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $vote['Vote']['id'])); ?>
+ Html->link(__('List Votes', true), array('action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/edit.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/edit.ctp
new file mode 100644
index 000000000..4ddbab111
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/edit.ctp
@@ -0,0 +1,24 @@
+
+Form->create('Vote');?>
+
+
+ Form->input('id');
+ echo $this->Form->input('translation_id');
+ echo $this->Form->input('user_id');
+ ?>
+
+Form->end(__('Submit', true));?>
+
+
+
+
+
+ Html->link(__('Delete', true), array('action' => 'delete', $this->Form->value('Vote.id')), null, sprintf(__('Are you sure you want to delete # %s?', true), $this->Form->value('Vote.id'))); ?>
+ Html->link(__('List Votes', true), array('action' => 'index'));?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/index.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/index.ctp
new file mode 100644
index 000000000..ec5ae6db7
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/index.ctp
@@ -0,0 +1,63 @@
+
+
+
+
+ Paginator->sort('id');?>
+ Paginator->sort('translation_id');?>
+ Paginator->sort('user_id');?>
+ Paginator->sort('created');?>
+ Paginator->sort('modified');?>
+
+
+
+ >
+
+
+ Html->link($vote['Translation']['translation_text'], array('controller' => 'translations', 'action' => 'view', $vote['Translation']['id'])); ?>
+
+
+ Html->link($vote['User']['name'], array('controller' => 'users', 'action' => 'view', $vote['User']['id'])); ?>
+
+
+
+
+ Html->link(__('View', true), array('action' => 'view', $vote['Vote']['id'])); ?>
+ Html->link(__('Edit', true), array('action' => 'edit', $vote['Vote']['id'])); ?>
+ Html->link(__('Delete', true), array('action' => 'delete', $vote['Vote']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $vote['Vote']['id'])); ?>
+
+
+
+
+
+ Paginator->counter(array(
+ 'format' => __('Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%', true)
+ ));
+ ?>
+
+
+ Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>
+ | Paginator->numbers();?>
+ |
+ Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>
+
+
+
+
+
+ Html->link(__('New Vote', true), array('action' => 'add')); ?>
+
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/views/votes/view.ctp b/code/ryzom/tools/server/www/webtt/app/views/votes/view.ctp
new file mode 100644
index 000000000..ee5e7e265
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/views/votes/view.ctp
@@ -0,0 +1,43 @@
+
+
+
+ >
+ >
+
+
+
+ >
+ >
+ Html->link($vote['Translation']['translation_text'], array('controller' => 'translations', 'action' => 'view', $vote['Translation']['id'])); ?>
+
+
+ >
+ >
+ Html->link($vote['User']['name'], array('controller' => 'users', 'action' => 'view', $vote['User']['id'])); ?>
+
+
+ >
+ >
+
+
+
+ >
+ >
+
+
+
+
+
+
+
+
+ Html->link(__('Edit Vote', true), array('action' => 'edit', $vote['Vote']['id'])); ?>
+ Html->link(__('Delete Vote', true), array('action' => 'delete', $vote['Vote']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $vote['Vote']['id'])); ?>
+ Html->link(__('List Votes', true), array('action' => 'index')); ?>
+ Html->link(__('New Vote', true), array('action' => 'add')); ?>
+ Html->link(__('List Translations', true), array('controller' => 'translations', 'action' => 'index')); ?>
+ Html->link(__('New Translation', true), array('controller' => 'translations', 'action' => 'add')); ?>
+ Html->link(__('List Users', true), array('controller' => 'users', 'action' => 'index')); ?>
+ Html->link(__('New User', true), array('controller' => 'users', 'action' => 'add')); ?>
+
+
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/960.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/960.css
new file mode 100755
index 000000000..6db1bd34c
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/960.css
@@ -0,0 +1,491 @@
+/*
+ 960 Grid System ~ Core CSS.
+ Learn more ~ http://960.gs/
+
+ Licensed under GPL and MIT.
+*/
+
+/* =Containers
+--------------------------------------------------------------------------------*/
+
+.container_12,
+.container_16
+{
+ margin-left: auto;
+ margin-right: auto;
+ width: 960px;
+}
+
+/* =Grid >> Global
+--------------------------------------------------------------------------------*/
+
+.grid_1,
+.grid_2,
+.grid_3,
+.grid_4,
+.grid_5,
+.grid_6,
+.grid_7,
+.grid_8,
+.grid_9,
+.grid_10,
+.grid_11,
+.grid_12,
+.grid_13,
+.grid_14,
+.grid_15,
+.grid_16
+{
+ display: inline;
+ float: left;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.container_12 .grid_3,
+.container_16 .grid_4
+{
+ width: 220px;
+}
+
+.container_12 .grid_6,
+.container_16 .grid_8
+{
+ width: 460px;
+}
+
+.container_12 .grid_9,
+.container_16 .grid_12
+{
+ width: 700px;
+}
+
+.container_12 .grid_12,
+.container_16 .grid_16
+{
+ width: 940px;
+}
+
+/* =Grid >> Children (Alpha ~ First, Omega ~ Last)
+--------------------------------------------------------------------------------*/
+
+.alpha
+{
+ margin-left: 0;
+}
+
+.omega
+{
+ margin-right: 0;
+}
+
+/* =Grid >> 12 Columns
+--------------------------------------------------------------------------------*/
+
+.container_12 .grid_1
+{
+ width: 60px;
+}
+
+.container_12 .grid_2
+{
+ width: 140px;
+}
+
+.container_12 .grid_4
+{
+ width: 300px;
+}
+
+.container_12 .grid_5
+{
+ width: 380px;
+}
+
+.container_12 .grid_7
+{
+ width: 540px;
+}
+
+.container_12 .grid_8
+{
+ width: 620px;
+}
+
+.container_12 .grid_10
+{
+ width: 780px;
+}
+
+.container_12 .grid_11
+{
+ width: 860px;
+}
+
+/* =Grid >> 16 Columns
+--------------------------------------------------------------------------------*/
+
+.container_16 .grid_1
+{
+ width: 40px;
+}
+
+.container_16 .grid_2
+{
+ width: 100px;
+}
+
+.container_16 .grid_3
+{
+ width: 160px;
+}
+
+.container_16 .grid_5
+{
+ width: 280px;
+}
+
+.container_16 .grid_6
+{
+ width: 340px;
+}
+
+.container_16 .grid_7
+{
+ width: 400px;
+}
+
+.container_16 .grid_9
+{
+ width: 520px;
+}
+
+.container_16 .grid_10
+{
+ width: 580px;
+}
+
+.container_16 .grid_11
+{
+ width: 640px;
+}
+
+.container_16 .grid_13
+{
+ width: 760px;
+}
+
+.container_16 .grid_14
+{
+ width: 820px;
+}
+
+.container_16 .grid_15
+{
+ width: 880px;
+}
+
+/* =Prefix Extra Space >> Global
+--------------------------------------------------------------------------------*/
+
+.container_12 .prefix_3,
+.container_16 .prefix_4
+{
+ padding-left: 240px;
+}
+
+.container_12 .prefix_6,
+.container_16 .prefix_8
+{
+ padding-left: 480px;
+}
+
+.container_12 .prefix_9,
+.container_16 .prefix_12
+{
+ padding-left: 720px;
+}
+
+/* =Prefix Extra Space >> 12 Columns
+--------------------------------------------------------------------------------*/
+
+.container_12 .prefix_1
+{
+ padding-left: 80px;
+}
+
+.container_12 .prefix_2
+{
+ padding-left: 160px;
+}
+
+.container_12 .prefix_4
+{
+ padding-left: 320px;
+}
+
+.container_12 .prefix_5
+{
+ padding-left: 400px;
+}
+
+.container_12 .prefix_7
+{
+ padding-left: 560px;
+}
+
+.container_12 .prefix_8
+{
+ padding-left: 640px;
+}
+
+.container_12 .prefix_10
+{
+ padding-left: 800px;
+}
+
+.container_12 .prefix_11
+{
+ padding-left: 880px;
+}
+
+/* =Prefix Extra Space >> 16 Columns
+--------------------------------------------------------------------------------*/
+
+.container_16 .prefix_1
+{
+ padding-left: 60px;
+}
+
+.container_16 .prefix_2
+{
+ padding-left: 120px;
+}
+
+.container_16 .prefix_3
+{
+ padding-left: 180px;
+}
+
+.container_16 .prefix_5
+{
+ padding-left: 300px;
+}
+
+.container_16 .prefix_6
+{
+ padding-left: 360px;
+}
+
+.container_16 .prefix_7
+{
+ padding-left: 420px;
+}
+
+.container_16 .prefix_9
+{
+ padding-left: 540px;
+}
+
+.container_16 .prefix_10
+{
+ padding-left: 600px;
+}
+
+.container_16 .prefix_11
+{
+ padding-left: 660px;
+}
+
+.container_16 .prefix_13
+{
+ padding-left: 780px;
+}
+
+.container_16 .prefix_14
+{
+ padding-left: 840px;
+}
+
+.container_16 .prefix_15
+{
+ padding-left: 900px;
+}
+
+/* =Suffix Extra Space >> Global
+--------------------------------------------------------------------------------*/
+
+.container_12 .suffix_3,
+.container_16 .suffix_4
+{
+ padding-right: 240px;
+}
+
+.container_12 .suffix_6,
+.container_16 .suffix_8
+{
+ padding-right: 480px;
+}
+
+.container_12 .suffix_9,
+.container_16 .suffix_12
+{
+ padding-right: 720px;
+}
+
+/* =Suffix Extra Space >> 12 Columns
+--------------------------------------------------------------------------------*/
+
+.container_12 .suffix_1
+{
+ padding-right: 80px;
+}
+
+.container_12 .suffix_2
+{
+ padding-right: 160px;
+}
+
+.container_12 .suffix_4
+{
+ padding-right: 320px;
+}
+
+.container_12 .suffix_5
+{
+ padding-right: 400px;
+}
+
+.container_12 .suffix_7
+{
+ padding-right: 560px;
+}
+
+.container_12 .suffix_8
+{
+ padding-right: 640px;
+}
+
+.container_12 .suffix_10
+{
+ padding-right: 800px;
+}
+
+.container_12 .suffix_11
+{
+ padding-right: 880px;
+}
+
+/* =Suffix Extra Space >> 16 Columns
+--------------------------------------------------------------------------------*/
+
+.container_16 .suffix_1
+{
+ padding-right: 60px;
+}
+
+.container_16 .suffix_2
+{
+ padding-right: 120px;
+}
+
+.container_16 .suffix_3
+{
+ padding-right: 180px;
+}
+
+.container_16 .suffix_5
+{
+ padding-right: 300px;
+}
+
+.container_16 .suffix_6
+{
+ padding-right: 360px;
+}
+
+.container_16 .suffix_7
+{
+ padding-right: 420px;
+}
+
+.container_16 .suffix_9
+{
+ padding-right: 540px;
+}
+
+.container_16 .suffix_10
+{
+ padding-right: 600px;
+}
+
+.container_16 .suffix_11
+{
+ padding-right: 660px;
+}
+
+.container_16 .suffix_13
+{
+ padding-right: 780px;
+}
+
+.container_16 .suffix_14
+{
+ padding-right: 840px;
+}
+
+.container_16 .suffix_15
+{
+ padding-right: 900px;
+}
+
+/* =Clear Floated Elements
+--------------------------------------------------------------------------------*/
+
+/* http://sonspring.com/journal/clearing-floats */
+
+html body * span.clear,
+html body * div.clear,
+html body * li.clear,
+html body * dd.clear
+{
+ background: none;
+ border: 0;
+ clear: both;
+ display: block;
+ float: none;
+ font-size: 0;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ visibility: hidden;
+ width: 0;
+ height: 0;
+}
+
+/* http://www.positioniseverything.net/easyclearing.html */
+
+.clearfix:after
+{
+ clear: both;
+ content: '.';
+ display: block;
+ visibility: hidden;
+ height: 0;
+}
+
+.clearfix
+{
+ display: inline-block;
+}
+
+* html .clearfix
+{
+ height: 1%;
+}
+
+.clearfix
+{
+ display: block;
+}
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/grid.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/grid.css
new file mode 100755
index 000000000..dd21d4e56
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/grid.css
@@ -0,0 +1,491 @@
+/*
+ 960 Grid System ~ Core CSS.
+ Learn more ~ http://960.gs/
+
+ Licensed under GPL and MIT.
+*/
+
+/* =Containers
+--------------------------------------------------------------------------------*/
+
+.container_12,
+.container_16
+{
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+}
+
+/* =Grid >> Global
+--------------------------------------------------------------------------------*/
+
+.grid_1,
+.grid_2,
+.grid_3,
+.grid_4,
+.grid_5,
+.grid_6,
+.grid_7,
+.grid_8,
+.grid_9,
+.grid_10,
+.grid_11,
+.grid_12,
+.grid_13,
+.grid_14,
+.grid_15,
+.grid_16
+{
+ display: inline;
+ float: left;
+ margin-left: 1%;
+ margin-right: 1%;
+}
+
+.container_12 .grid_3,
+.container_16 .grid_4
+{
+ width: 23%;
+}
+
+.container_12 .grid_6,
+.container_16 .grid_8
+{
+ width: 48%;
+}
+
+.container_12 .grid_9,
+.container_16 .grid_12
+{
+ width: 73%;
+}
+
+.container_12 .grid_12,
+.container_16 .grid_16
+{
+ width: 98%;
+}
+
+/* =Grid >> Children (Alpha ~ First, Omega ~ Last)
+--------------------------------------------------------------------------------*/
+
+.alpha
+{
+ margin-left: 0;
+}
+
+.omega
+{
+ margin-right: 0;
+}
+
+/* =Grid >> 12 Columns
+--------------------------------------------------------------------------------*/
+
+.container_12 .grid_1
+{
+ width: 6.333%;
+}
+
+.container_12 .grid_2
+{
+ width: 14.666%;
+}
+
+.container_12 .grid_4
+{
+ width: 31.333%;
+}
+
+.container_12 .grid_5
+{
+ width: 39.666%;
+}
+
+.container_12 .grid_7
+{
+ width: 56.333%;
+}
+
+.container_12 .grid_8
+{
+ width: 64.666%;
+}
+
+.container_12 .grid_10
+{
+ width: 81.333%;
+}
+
+.container_12 .grid_11
+{
+ width: 89.666%;
+}
+
+/* =Grid >> 16 Columns
+--------------------------------------------------------------------------------*/
+
+.container_16 .grid_1
+{
+ width: 4.25%;
+}
+
+.container_16 .grid_2
+{
+ width: 10.5%;
+}
+
+.container_16 .grid_3
+{
+ width: 16.75%;
+}
+
+.container_16 .grid_5
+{
+ width: 29.25%;
+}
+
+.container_16 .grid_6
+{
+ width: 35.5%;
+}
+
+.container_16 .grid_7
+{
+ width: 41.75%;
+}
+
+.container_16 .grid_9
+{
+ width: 54.25%;
+}
+
+.container_16 .grid_10
+{
+ width: 60.5%;
+}
+
+.container_16 .grid_11
+{
+ width: 66.75%;
+}
+
+.container_16 .grid_13
+{
+ width: 79.25%;
+}
+
+.container_16 .grid_14
+{
+ width: 85.5%;
+}
+
+.container_16 .grid_15
+{
+ width: 91.75%;
+}
+
+/* =Prefix Extra Space >> Global
+--------------------------------------------------------------------------------*/
+
+.container_12 .prefix_3,
+.container_16 .prefix_4
+{
+ padding-left: 25%;
+}
+
+.container_12 .prefix_6,
+.container_16 .prefix_8
+{
+ padding-left: 50%;
+}
+
+.container_12 .prefix_9,
+.container_16 .prefix_12
+{
+ padding-left: 75%;
+}
+
+/* =Prefix Extra Space >> 12 Columns
+--------------------------------------------------------------------------------*/
+
+.container_12 .prefix_1
+{
+ padding-left: 8.333%;
+}
+
+.container_12 .prefix_2
+{
+ padding-left: 16.666%;
+}
+
+.container_12 .prefix_4
+{
+ padding-left: 33.333%;
+}
+
+.container_12 .prefix_5
+{
+ padding-left: 41.666%;
+}
+
+.container_12 .prefix_7
+{
+ padding-left: 58.333%;
+}
+
+.container_12 .prefix_8
+{
+ padding-left: 66.666%;
+}
+
+.container_12 .prefix_10
+{
+ padding-left: 83.333%;
+}
+
+.container_12 .prefix_11
+{
+ padding-left: 91.666%;
+}
+
+/* =Prefix Extra Space >> 16 Columns
+--------------------------------------------------------------------------------*/
+
+.container_16 .prefix_1
+{
+ padding-left: 6.25%;
+}
+
+.container_16 .prefix_2
+{
+ padding-left: 12.5%;
+}
+
+.container_16 .prefix_3
+{
+ padding-left: 18.75%;
+}
+
+.container_16 .prefix_5
+{
+ padding-left: 31.25%;
+}
+
+.container_16 .prefix_6
+{
+ padding-left: 37.5%;
+}
+
+.container_16 .prefix_7
+{
+ padding-left: 43.75%;
+}
+
+.container_16 .prefix_9
+{
+ padding-left: 56.25%;
+}
+
+.container_16 .prefix_10
+{
+ padding-left: 62.5%;
+}
+
+.container_16 .prefix_11
+{
+ padding-left: 68.75%;
+}
+
+.container_16 .prefix_13
+{
+ padding-left: 81.25%;
+}
+
+.container_16 .prefix_14
+{
+ padding-left: 87.5%;
+}
+
+.container_16 .prefix_15
+{
+ padding-left: 93.75%;
+}
+
+/* =Suffix Extra Space >> Global
+--------------------------------------------------------------------------------*/
+
+.container_12 .suffix_3,
+.container_16 .suffix_4
+{
+ padding-right: 25%;
+}
+
+.container_12 .suffix_6,
+.container_16 .suffix_8
+{
+ padding-right: 50%;
+}
+
+.container_12 .suffix_9,
+.container_16 .suffix_12
+{
+ padding-right: 75%;
+}
+
+/* =Suffix Extra Space >> 12 Columns
+--------------------------------------------------------------------------------*/
+
+.container_12 .suffix_1
+{
+ padding-right: 8.333%;
+}
+
+.container_12 .suffix_2
+{
+ padding-right: 16.666%;
+}
+
+.container_12 .suffix_4
+{
+ padding-right: 33.333%;
+}
+
+.container_12 .suffix_5
+{
+ padding-right: 41.666%;
+}
+
+.container_12 .suffix_7
+{
+ padding-right: 58.333%;
+}
+
+.container_12 .suffix_8
+{
+ padding-right: 66.666%;
+}
+
+.container_12 .suffix_10
+{
+ padding-right: 83.333%;
+}
+
+.container_12 .suffix_11
+{
+ padding-right: 91.666%;
+}
+
+/* =Suffix Extra Space >> 16 Columns
+--------------------------------------------------------------------------------*/
+
+.container_16 .suffix_1
+{
+ padding-right: 6.25%;
+}
+
+.container_16 .suffix_2
+{
+ padding-right: 16.5%;
+}
+
+.container_16 .suffix_3
+{
+ padding-right: 18.75%;
+}
+
+.container_16 .suffix_5
+{
+ padding-right: 31.25%;
+}
+
+.container_16 .suffix_6
+{
+ padding-right: 37.5%;
+}
+
+.container_16 .suffix_7
+{
+ padding-right: 43.75%;
+}
+
+.container_16 .suffix_9
+{
+ padding-right: 56.25%;
+}
+
+.container_16 .suffix_10
+{
+ padding-right: 62.5%;
+}
+
+.container_16 .suffix_11
+{
+ padding-right: 68.75%;
+}
+
+.container_16 .suffix_13
+{
+ padding-right: 81.25%;
+}
+
+.container_16 .suffix_14
+{
+ padding-right: 87.5%;
+}
+
+.container_16 .suffix_15
+{
+ padding-right: 93.75%;
+}
+
+/* =Clear Floated Elements
+--------------------------------------------------------------------------------*/
+
+/* http://sonspring.com/journal/clearing-floats */
+
+html body * span.clear,
+html body * div.clear,
+html body * li.clear,
+html body * dd.clear
+{
+ background: none;
+ border: 0;
+ clear: both;
+ display: block;
+ float: none;
+ font-size: 0;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ visibility: hidden;
+ width: 0;
+ height: 0;
+}
+
+/* http://www.positioniseverything.net/easyclearing.html */
+
+.clearfix:after
+{
+ clear: both;
+ content: '.';
+ display: block;
+ visibility: hidden;
+ height: 0;
+}
+
+.clearfix
+{
+ display: inline-block;
+}
+
+* html .clearfix
+{
+ height: 1%;
+}
+
+.clearfix
+{
+ display: block;
+}
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/ie.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/ie.css
new file mode 100755
index 000000000..7fe61ff28
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/ie.css
@@ -0,0 +1,31 @@
+/*
+ Fluid 960 Grid System - IE Fixes (IE7 and greater)
+ Learn more ~ http://www.designinfluences.com/
+
+ Licensed under GPL and MIT.
+*/
+
+/* =Grid >> Global
+--------------------------------------------------------------------------------*/
+
+.grid_1,
+.grid_2,
+.grid_3,
+.grid_4,
+.grid_5,
+.grid_6,
+.grid_7,
+.grid_8,
+.grid_9,
+.grid_10,
+.grid_11,
+.grid_12,
+.grid_13,
+.grid_14,
+.grid_15,
+.grid_16
+{
+ margin-left: .92%;
+ margin-right: .92%;
+}
+
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/ie6.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/ie6.css
new file mode 100755
index 000000000..b1ff5b5ce
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/ie6.css
@@ -0,0 +1,31 @@
+/*
+ Fluid 960 Grid System - IE6 Fixes
+ Learn more ~ http://www.designinfluences.com/
+
+ Licensed under GPL and MIT.
+*/
+
+/* =Grid >> Global
+--------------------------------------------------------------------------------*/
+
+.grid_1,
+.grid_2,
+.grid_3,
+.grid_4,
+.grid_5,
+.grid_6,
+.grid_7,
+.grid_8,
+.grid_9,
+.grid_10,
+.grid_11,
+.grid_12,
+.grid_13,
+.grid_14,
+.grid_15,
+.grid_16
+{
+ margin-left: .8%;
+ margin-right: .8%;
+}
+
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/layout.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/layout.css
new file mode 100755
index 000000000..1c88c6c95
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/layout.css
@@ -0,0 +1,675 @@
+/*
+-----------------------------------------------
+Grey Box Method - Layout CSS
+----------------------------------------------- */
+
+body {
+ background: #eee;
+ border-top: 5px solid #000;
+ color: #333;
+ font-size: 11px;
+ padding: 0 0 40px;
+}
+
+
+/* anchors
+----------------------------------------------- */
+a {
+ color: #000;
+ font-weight:bold;
+ text-decoration: none;
+}
+a:hover {
+ color:#333;
+}
+
+
+/* 960 grid system container background
+----------------------------------------------- */
+.container_12,
+.container_16 {
+ background:#fff;
+}
+
+
+/* headings
+----------------------------------------------- */
+h1, h2, h3, h4, h5, h6 {line-height:1.2em; margin-bottom:.3em;}
+h2 {margin-top:1em;}
+h5 {font-size:1.2em;}
+h6 {font-size:1em; text-transform:uppercase;}
+
+
+h1 a {
+ font-weight:normal;
+}
+
+
+/* branding
+----------------------------------------------- */
+h1#branding {
+ font-weight:normal;
+ font-size:3em;
+ text-align:left;
+ background:#aaa;
+ padding:.7em 1em;
+ margin-bottom:0;
+}
+
+
+/* page heading
+----------------------------------------------- */
+h2#page-heading {
+ font-weight:normal;
+ padding:.5em;
+ margin:0 0 10px 0;
+ border-bottom:1px solid #ccc;
+}
+
+
+/* boxes
+----------------------------------------------- */
+.box {
+ background:#ddd;
+ margin-bottom:20px;
+ padding:10px 10px 1px 10px;
+}
+.box h2 {
+ font-size:1em;
+ font-weight:normal;
+ text-transform:uppercase;
+ color:#fff;
+ background:#333;
+ margin:-10px -10px 0 -10px;
+ padding:6px 12px;
+}
+.box h2 a,
+.box h2 a.visible {
+ color:#fff;
+ background:#333 url("../img/switch_minus.gif") 97% 50% no-repeat;
+ display:block;
+ padding:6px 12px;
+ margin:-6px -12px;
+ border:none;
+}
+.grid_4 .box h2 a {
+ background-position: 97% 50%;
+}
+.grid_5 .box h2 a {
+ background-position: 98% 50%;
+}
+.grid_12 .box h2 a {
+ background-position: 99% 50%;
+}
+
+
+.box h2 a.hidden,
+.box h2 a.hidden:hover {
+ background-image: url("../img/switch_plus.gif");
+}
+.box h2 a:hover {
+ background-color:#111;
+}
+.block {
+ padding-top:10px;
+}
+div.menu {
+ padding:0;
+}
+div.menu h2 {
+ margin:0;
+}
+div.menu .block {
+ padding-top:0;
+}
+
+
+/* paragraphs, quotes and lists
+----------------------------------------------- */
+p {
+ margin-bottom:1em;
+}
+blockquote {
+ font-family: Georgia, 'Times New Roman', serif;
+ font-size:1.2em;
+ padding-left:1em;
+ border-left:4px solid #ccc;
+}
+blockquote cite {
+ font-size:.9em;
+}
+ul, ol {
+ padding-top:0;
+}
+
+
+/* menus
+----------------------------------------------- */
+ul.menu {
+ list-style:none;
+ border-top:1px solid #bbb;
+}
+ul.menu li {
+ margin:0;
+}
+ul.menu li a {
+ display:block;
+ padding:4px 10px;
+ border-bottom:1px solid #ccc;
+}
+ul.menu li a:hover {
+ background:#eee;
+}
+ul.menu li a:active {
+ background:#ccc;
+}
+
+
+/* submenus
+----------------------------------------------- */
+ul.menu ul {
+ list-style:none;
+ margin:0;
+}
+ul.menu ul li a {
+ padding-left:30px;
+}
+
+
+/* section menus
+----------------------------------------------- */
+ul.section {
+ border-top:0;
+ margin-bottom:0;
+}
+ul.section li {
+ text-transform:uppercase;
+}
+ul.section li a {
+ background:#bbb;
+}
+ul.section li a:hover {
+ background:#aaa;
+}
+ul.section li a:active {
+ color:#fff;
+ background:#666;
+}
+ul.section li li a {
+ background:#ddd;
+ border-bottom:1px solid #eee;
+}
+ul.section li li a:hover {
+ background:#ccc;
+}
+ul.section li li a:active {
+ color:#000;
+ background:#fff;
+}
+ul.section ul li {
+ text-transform:none;
+}
+ul.section ul.current li a {
+ background:#eee;
+ border-bottom:1px solid #fff;
+}
+ul.section ul.current li a:hover {
+ background:#ddd;
+}
+ul.section ul.current li a:active {
+ background:#fff;
+}
+ul.section li a.current {
+ color:#fff;
+ background:#666;
+}
+ul.section li a.current:hover {
+ background:#555;
+}
+ul.section li a.current:active {
+ background:#444;
+}
+ul.section li a.active {
+ background:#fff;
+ cursor:default;
+}
+ul.section li.current > a.active,
+ul.section li.current > a.active:hover {
+ color:#fff;
+ background:#666;
+ cursor:default;
+}
+
+
+/* table
+----------------------------------------------- */
+table {
+ width:100%;
+ border:1px solid #bbb;
+ margin-bottom:10px;
+}
+col.colC {
+ width:8em;
+}
+th, td {
+ padding:.2em 1em;
+ text-align:left;
+}
+thead th {
+ border-bottom:2px solid #888;
+ background:#bbb;
+ padding:.4em 1em .2em;
+}
+thead th.table-head {
+ font-size:1em;
+ font-weight:normal;
+ text-transform:uppercase;
+ color:#fff;
+ background:#555;
+ border:1px solid #555;
+}
+tbody th,
+tbody td {
+ border-top:1px solid #bbb;
+ border-bottom:1px solid #bbb;
+ background:#eee;
+}
+tbody tr.odd th,
+tbody tr.odd td {
+ background:#fff;
+}
+tfoot th,
+tfoot td {
+ border-top:2px solid #666;
+ background:#eee;
+}
+tfoot tr.total th,
+tfoot tr.total td {
+ border-top:6px double #666;
+}
+tfoot tr.total th {
+ text-transform:uppercase;
+}
+th.currency,
+td.currency {
+ text-align:right;
+}
+tfoot.dark th, tfoot.dark td {
+ background: #bbbbbb;
+}
+
+
+/* forms
+----------------------------------------------- */
+form {
+ overflow:hidden;
+}
+fieldset {
+ border:1px solid #bbb;
+ padding:10px;
+ position:relative;
+ background:#e9e9e9;
+ margin-bottom:10px;
+}
+legend {
+ font-size:1.1em;
+ padding:.4em .8em;
+ background:#fff;
+ border:1px solid #bbb;
+}
+fieldset.login p {
+ margin-bottom:1em;
+ margin-top:0pt;
+}
+fieldset p label {
+ width:98%;
+}
+fieldset p input {
+ width:98%;
+}
+fieldset p select {
+ width:99%;
+}
+fieldset.login p label {
+ float:left;
+ line-height:2em;
+ margin-right:3%;
+ text-align:right;
+ width:32%;
+}
+fieldset.login p input {
+ width:60%;
+}
+fieldset.login input.button {
+ margin-left:35%;
+}
+form p.notice {
+ font-weight:bold;
+}
+input.search.text {
+ width:66%;
+}
+input.search.button {
+ width:28%;
+ margin-left:2%;
+}
+
+
+/* articles
+----------------------------------------------- */
+.articles {
+ padding:0;
+}
+.articles h2 {
+ margin:0;
+}
+#articles {
+ padding-top:0;
+}
+.article {
+ border-top:1px solid #666;
+ padding-top:.5em;
+}
+.box .article {
+ border-top:3px solid #fff;
+ padding:13px 10px 0 10px;
+}
+.article h2 {
+ font-size:2em;
+ font-weight:normal;
+ text-transform:none;
+ color:#333;
+ background:transparent;
+ padding:0;
+ margin:0;
+ border:none;
+}
+.article h3 {
+ margin-bottom:.2em;
+ font-size:1.6em;
+}
+.box .first {
+ border-top:none;
+}
+.article h4 {
+ font-size:1.2em;
+ text-transform:uppercase;
+ margin-bottom:.5em;
+}
+.article a.image {
+ float:left;
+ margin:3px 10px 3px 0;
+ padding:4px;
+ border:1px solid #bbb;
+ background:#fff;
+}
+.article a.image:hover {
+ border:1px solid #666;
+}
+.article a.image img {
+ float:left;
+}
+.article p.meta {
+ color:#666;
+ border-top:1px dotted #999;
+ border-bottom:1px dotted #999;
+ padding:.3em 0;
+ margin-bottom:.8em;
+}
+
+
+/* site information
+----------------------------------------------- */
+#site_info .box {
+ color:#ccc;
+ background:#666;
+ margin-bottom:10px;
+}
+#site_info a {
+ color:#fff;
+}
+#site_info a:hover {
+ color:#000;
+}
+
+
+/* AJAX sliding shelf
+----------------------------------------------- */
+#loading {float:right; margin-right:14px; margin-top:-2px;}
+.block {padding-bottom:1px;}
+
+
+/* Accordian
+----------------------------------------------- */
+.toggler {
+ color: #222;
+ margin: 0;
+ padding: 2px 5px;
+ background: #eee;
+ border-bottom: 1px solid #ddd;
+ border-right: 1px solid #ddd;
+ border-top: 1px solid #f5f5f5;
+ border-left: 1px solid #f5f5f5;
+ font-size:1.1em;
+ font-weight: normal;
+}
+.element h4 {
+ margin: 0;
+ padding:4px;
+ line-height:1.2em;
+}
+.element p {
+ margin: 0;
+ padding: 4px;
+}
+.float-right {
+ padding:10px 20px;
+ float:right;
+}
+
+#accordian-block {
+ padding-bottom:10px;
+}
+
+
+/* Mootools Kwicks
+----------------------------------------------- */
+#kwick-box {
+ padding:0;
+ overflow:hidden;
+}
+#kwick-box h2 {
+ margin:0;
+}
+#kwick {
+ position: relative;
+}
+#kwick .kwicks {
+ display: block;
+ background: #999;
+ height: 120px;
+ list-style:none;
+ margin:0;
+ overflow:hidden;
+}
+#kwick li {
+ float: left;
+ margin:0;
+ padding:0;
+}
+#kwick .kwick {
+ display: block;
+ cursor: pointer;
+ overflow: hidden;
+ height: 100px;
+ width: 215px;
+ padding: 10px;
+ background: #fff;
+}
+#kwick .kwick span {
+ color:#fff;
+}
+#kwick .one {
+ background: #666;
+}
+#kwick .two {
+ background: #777;
+}
+#kwick .three {
+ background: #888;
+}
+#kwick .four {
+ background: #999;
+}
+/* Main Nav Current States */
+ul.nav li a.current {
+ background: #888;
+}
+
+/* CakePHP Specific */
+div#flashMessage {
+ padding: 10px;
+ margin: 0px 13px 10px 11px;
+ border: 1px dashed #888;
+ background: #eee;
+ font-size: 14px;
+}
+div.flash-error {
+ color: #bf0000;
+ background: #ffbfbf !important;
+ border-color: #bf0000 !important;
+}
+div.flash-warning {
+ color: #725600;
+ background: #ffffbf !important;
+ border-color: #bfbf00 !important;
+}
+div.flash-success {
+ color: #00bf00;
+ background: #dfffbf !important;
+ border-color: #00bf00 !important;
+}
+div.error-message {
+ color: #bf0000;
+ font-weight: bold;
+}
+.input {
+ margin: 0px 0px 5px 0px;
+}
+.text input {
+ width: 250px;
+}
+.input label {
+ width: 100px;
+ text-align: right;
+ display: block;
+ float: left;
+ margin: 0px 5px 0px 0px;
+ padding: 2px 0px 0px 0px;
+}
+.text label {
+ padding: 6px 0px 0px 0px;
+}
+.form-submit-group {
+ float: right;
+ margin: 0px 0px 5px 0px;
+}
+.form-submit-group .submit {
+ float: left;
+}
+.form-cancel {
+ float: left;
+ padding-top: 5px;
+ margin-right: 5px;
+}
+/** Scaffold View **/
+dl {
+ line-height: 2em;
+ margin: 0em 0em;
+ width: 60%;
+}
+dl .altrow {
+ background: #f4f4f4;
+}
+dt {
+ font-weight: bold;
+ padding-left: 4px;
+ vertical-align: top;
+}
+dd {
+ margin-left: 10em;
+ margin-top: -2em;
+ vertical-align: top;
+}
+/** CakePHP Notices and Errors **/
+div.message {
+ clear: both;
+ color: #333;
+ font-size: 140%;
+ font-weight: bold;
+ margin: 0 0 1em 0;
+ background: #c73e14;
+ padding: 5px;
+}
+div.error-message {
+ clear: both;
+ color: #bf0000;
+ background: #ffbfbf;
+ border-color: #bf0000;
+ font-weight: bold;
+}
+p.error {
+ color: #bf0000;
+ background: #ffbfbf;
+ border-color: #bf0000;
+ font-family: Courier, monospace;
+ font-size: 120%;
+ line-height: 140%;
+ padding: 0.8em;
+ margin: 1em 0;
+}
+p.error em {
+ color: #000;
+ font-weight: normal;
+ line-height: 140%;
+}
+.notice {
+ color: #725600;
+ background: #ffffbf;
+ border-color: #bfbf00;
+ display: block;
+ font-family: Courier, monospace;
+ font-size: 120%;
+ line-height: 140%;
+ padding: 0.8em;
+ margin: 1em 0;
+}
+.success {
+ color: #00bf00;
+ background: #dfffbf;
+ border-color: #00bf00;
+}
+
+/* jQuery UI Stuff */
+#ui-datepicker-div {
+ background: #fff;
+ padding: 5px;
+ border: 1px solid #eee;
+}
+a.ui-datepicker-prev {
+ width: 35px;
+ float: left;
+ text-align: left;
+}
+a.ui-datepicker-next {
+ width: 35px;
+ float: right;
+ text-align: right;
+}
+div.ui-datepicker-title {
+ text-align: center;
+}
+table.ui-datepicker-calendar {
+ padding-bottom: 0px;
+ margin-bottom: 0px;
+}
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/nav.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/nav.css
new file mode 100755
index 000000000..53bff8d1e
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/nav.css
@@ -0,0 +1,167 @@
+/*
+-----------------------------------------------
+Navigation
+----------------------------------------------- */
+
+/* navigation (horizontal subnavigation)
+----------------------------------------------- */
+ul.nav,
+ul.nav * { margin:0;padding:0;}
+ul.nav {
+ position:relative;
+ background:#666;
+ max-width:100%;
+ height:2.5em;
+ }
+ul.nav li {
+ cursor:pointer;
+ float:left;
+ text-align:center;
+ list-style-type:none;
+ font-weight:normal;
+}
+ul.nav li ul {
+ cursor:default;
+ width:100%;
+ max-width:100%;
+ position:absolute;
+ height:auto;
+ top:2.5em;
+ background-position:0 0 !important;
+ left:-9000px;
+}
+ul.nav li ul li {
+ padding:0;
+ border:none;
+ width:auto;
+ max-width:none;
+}
+ul.nav li a {
+ color:#fff;
+ background:#666;
+ font-weight:bold;
+ text-decoration:none;
+ display:block;
+ float:left;
+ padding:0 1em;
+ height:2.4em;
+ line-height:2.5em;
+}
+ul.nav li ul li a {
+ position:relative !important; /* ie Mac */
+ cursor:pointer !important;
+ white-space:nowrap;
+ line-height:2em;
+ height:2em;
+ font-weight:normal;
+ color:#666;
+ background-position:0 50% !important;
+}
+
+ul.nav li:hover a,
+ul.nav li a:hover,
+ul.nav li a:focus {color:#000; background:#ccc;}
+ul.nav li a:active {color:#666; background:#fff;}
+ul.nav li:hover ul {left:0;z-index:10}
+ul.nav li ul,
+ul.nav li {background:#ccc !important}
+ul.nav li:hover ul li a {color:#444;}
+ul.nav li:hover ul li a:hover {color:#000; background:#fff;}
+ul.nav li:hover ul li a:active {color:#666; background:#fff;}
+
+ul.nav li.current a {color:#666; background:#fff; cursor:default; font-weight:bold;}
+ul.nav li.current ul {left:0;z-index:5}
+ul.nav li.current ul,
+ul.nav li.current {background:#ccc !important}
+ul.nav li.current ul li a {color:#444; background:#ccc; font-weight:normal;}
+ul.nav li.current ul li a:hover {color:#000; background:#fff;}
+ul.nav li ul li.current a,
+ul.nav li ul li.current a:hover,
+ul.nav li.current:hover ul li a:active {color:#666; background:#fff;}
+
+
+/* navigation (vertical subnavigation)
+----------------------------------------------- */
+ul.nav {
+ background:#666;
+}
+ul.main li {
+ position:relative;
+ top:0;
+ left:0;
+}
+ul.main li ul {
+ border-top:0;
+}
+ul.main li ul li {
+ float:left;
+}
+ul.main li a {
+ height:2.5em;
+ line-height:2.5em;
+ border:0;
+ color:#fff;
+ background:#666;
+}
+ul.main li ul li a {
+ width:12em;
+ line-height:2em;
+ height:2em;
+ text-align:left;
+ color:#fff;
+ border-top:1px solid #444;
+ background:#444;
+}
+ul.main li a:focus {color:#fff; background:#666;}
+ul.main li ul li a:hover {
+ color:#fff;
+ background:#555;
+}
+ul.main li:hover a {
+ color:#fff;
+ background:#555;
+}
+ul.main li:hover ul li a {color:#fff;}
+ul.main li:hover ul li a:hover {color:#fff; background:#444;}
+ul.main li:hover a:active {background:#444;}
+ul.main li:hover ul li a:active {color:#fff; background:#222;}
+
+
+/* secondary list
+----------------------------------------------- */
+ul.nav li.secondary {
+ float:right;
+ color:#cde;
+ background:transparent !important;
+}
+ul.nav li.secondary span.status {
+ float:left;
+ padding:0 1em;
+ line-height:2.77em;
+ height:2.77em;
+ font-size:0.9em;
+}
+ul.nav li.secondary span.status a {
+ float:none;
+ display:inline;
+ padding:0;
+ height:auto;
+ line-height:auto;
+ color:#cde;
+ background:transparent;
+}
+ul.nav li.secondary span.status a:hover {
+ color:#fff;
+ background:transparent;
+}
+ul.nav li.secondary span.status span {
+ text-transform:capitalize;
+}
+ul.nav li.secondary:hover a {
+ color:#fff;
+ background:#666;
+}
+ul.nav li.secondary:hover a:hover {
+ background:#555;
+}
+ul.nav li.secondary:hover a:active {background:#444;}
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/reset.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/reset.css
new file mode 100755
index 000000000..3aadd3dd6
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/reset.css
@@ -0,0 +1,53 @@
+/* http://meyerweb.com/eric/tools/css/reset/ */
+/* v1.0 | 20080212 */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+/* remember to define focus styles! */
+:focus {
+ outline: 0;
+}
+
+/* remember to highlight inserts somehow! */
+ins {
+ text-decoration: none;
+}
+del {
+ text-decoration: line-through;
+}
+
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/css/text.css b/code/ryzom/tools/server/www/webtt/app/webroot/css/text.css
new file mode 100755
index 000000000..b6a687bba
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/css/text.css
@@ -0,0 +1,98 @@
+/*
+ 960 Grid System ~ Text CSS.
+ Learn more ~ http://960.gs/
+
+ Licensed under GPL and MIT.
+*/
+
+/* =Basic HTML
+--------------------------------------------------------------------------------*/
+
+body
+{
+ font: 13px/1.5 Helvetica, Arial, 'Liberation Sans', FreeSans, sans-serif;
+}
+
+a:focus
+{
+ outline: 1px dotted invert;
+}
+
+hr
+{
+ border-color: #ccc;
+ border-style: solid;
+ border-width: 1px 0 0;
+ clear: both;
+ height: 0;
+}
+
+/* =Headings
+--------------------------------------------------------------------------------*/
+
+h1
+{
+ font-size: 25px;
+}
+
+h2
+{
+ font-size: 23px;
+}
+
+h3
+{
+ font-size: 21px;
+}
+
+h4
+{
+ font-size: 19px;
+}
+
+h5
+{
+ font-size: 17px;
+}
+
+h6
+{
+ font-size: 15px;
+}
+
+/* =Spacing
+--------------------------------------------------------------------------------*/
+
+ol
+{
+ list-style: decimal;
+}
+
+ul
+{
+ list-style: square;
+}
+
+li
+{
+ margin-left: 30px;
+}
+
+p,
+dl,
+hr,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+ol,
+ul,
+pre,
+table,
+address,
+fieldset
+{
+ margin-bottom: 20px;
+}
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/app/webroot/js/jquery-1.3.2.min.js b/code/ryzom/tools/server/www/webtt/app/webroot/js/jquery-1.3.2.min.js
new file mode 100644
index 000000000..b1ae21d8b
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/app/webroot/js/jquery-1.3.2.min.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,""]||!O.indexOf(""," "]||(!O.indexOf(""," "]||!O.indexOf(""," "]||!o.support.htmlSerialize&&[1,"div","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V ";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML=" ";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="
";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(Fa text ';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(/#', $result);
+ }
+
+/**
+ * test message creation
+ *
+ * @return void
+ */
+ function testMessage() {
+ $result = $this->Toolbar->message('test', 'one, two');
+ $expected = array(
+ 'assertTags($result, $expected);
+ }
+/**
+ * Test Table generation
+ *
+ * @return void
+ */
+ function testTable() {
+ $rows = array(
+ array(1,2),
+ array(3,4),
+ );
+ $result = $this->Toolbar->table($rows);
+ $expected = array(
+ 'table' => array('class' =>'debug-table'),
+ array('tr' => array('class' => 'odd')),
+ '
array('class' => 'even')),
+ ' assertTags($result, $expected);
+ }
+/**
+ * test starting a panel
+ *
+ * @return void
+ **/
+ function testStartPanel() {
+ $result = $this->Toolbar->panelStart('My Panel', 'my_panel');
+ $expected = array(
+ 'a' => array('href' => '#my_panel'),
+ 'My Panel',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+/**
+ * test ending a panel
+ *
+ * @return void
+ **/
+ function testPanelEnd() {
+ $result = $this->Toolbar->panelEnd();
+ $this->assertNull($result);
+ }
+/**
+ * reset the view paths
+ *
+ * @return void
+ **/
+ function endCase() {
+ App::build();
+ }
+
+/**
+ * tearDown
+ *
+ * @access public
+ * @return void
+ */
+ function tearDown() {
+ unset($this->Toolbar, $this->Controller);
+ ClassRegistry::removeObject('view');
+ ClassRegistry::flush();
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/cases/views/helpers/toolbar.test.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/cases/views/helpers/toolbar.test.php
new file mode 100644
index 000000000..81c914e73
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/cases/views/helpers/toolbar.test.php
@@ -0,0 +1,170 @@
+ 'pages', 'action' => 'display', 'home'));
+ Router::parse('/');
+
+ $this->Toolbar =& new ToolbarHelper(array(
+ 'output' => 'MockBackendHelper',
+ 'cacheKey' => 'debug_kit_toolbar_test_case',
+ 'cacheConfig' => 'default'
+ ));
+ $this->Toolbar->MockBackend = new MockBackendHelper();
+
+ $this->Controller =& ClassRegistry::init('Controller');
+ if (isset($this->_debug)) {
+ Configure::write('debug', $this->_debug);
+ }
+ }
+/**
+ * start Case - switch view paths
+ *
+ * @return void
+ **/
+ function startCase() {
+ $this->_viewPaths = App::path('views');
+ App::build(array(
+ 'views' => array(
+ TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
+ APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
+ ROOT . DS . LIBS . 'view' . DS
+ )), true);
+ $this->_debug = Configure::read('debug');
+ }
+/**
+ * test cache writing for views.
+ *
+ * @return void
+ **/
+ function testCacheWrite() {
+ $result = $this->Toolbar->writeCache('test', array('stuff', 'to', 'cache'));
+ $this->assertTrue($result);
+ }
+/**
+ * Ensure that the cache writing only affects the
+ * top most level of the history stack. As this is where the current request is stored.
+ *
+ * @return void
+ **/
+ function testOnlyWritingToFirstElement() {
+ $values = array(
+ array('test' => array('content' => array('first', 'values'))),
+ array('test' => array('content' => array('second', 'values'))),
+ );
+ Cache::write('debug_kit_toolbar_test_case', $values, 'default');
+ $this->Toolbar->writeCache('test', array('new', 'values'));
+
+ $result = $this->Toolbar->readCache('test');
+ $this->assertEqual($result, array('new', 'values'));
+
+ $result = $this->Toolbar->readCache('test', 1);
+ $this->assertEqual($result, array('second', 'values'));
+ }
+/**
+ * test cache reading for views
+ *
+ * @return void
+ **/
+ function testCacheRead() {
+ $result = $this->Toolbar->writeCache('test', array('stuff', 'to', 'cache'));
+ $this->assertTrue($result, 'Cache write failed %s');
+
+ $result = $this->Toolbar->readCache('test');
+ $this->assertEqual($result, array('stuff', 'to', 'cache'), 'Cache value is wrong %s');
+
+ $result = $this->Toolbar->writeCache('test', array('new', 'stuff'));
+ $this->assertTrue($result, 'Cache write failed %s');
+
+ $result = $this->Toolbar->readCache('test');
+ $this->assertEqual($result, array('new', 'stuff'), 'Cache value is wrong %s');
+ }
+/**
+ * Test that reading/writing doesn't work with no cache config.
+ *
+ * @return void
+ **/
+ function testNoCacheConfigPresent() {
+ $this->Toolbar = new ToolbarHelper(array('output' => 'MockBackendHelper'));
+
+ $result = $this->Toolbar->writeCache('test', array('stuff', 'to', 'cache'));
+ $this->assertFalse($result, 'Writing to cache succeeded with no cache config %s');
+
+ $result = $this->Toolbar->readCache('test');
+ $this->assertFalse($result, 'Reading cache succeeded with no cache config %s');
+ }
+/**
+ * ensure that getQueryLogs works and writes to the cache so the history panel will
+ * work.
+ *
+ * @return void
+ */
+ function testGetQueryLogs() {
+ $model =& new Model(array('ds' => 'test_suite', 'table' => 'posts', 'name' => 'Post'));
+ $model->find('all');
+ $model->find('first');
+
+ $result = $this->Toolbar->getQueryLogs('test_suite', array('cache' => false));
+ $this->assertTrue(is_array($result));
+ $this->assertTrue(count($result) >= 2, 'Should be more than 2 queries in the log %s');
+ $this->assertTrue(isset($result[0]['actions']));
+
+ $model->find('first');
+ Cache::delete('debug_kit_toolbar_test_case', 'default');
+ $result = $this->Toolbar->getQueryLogs('test_suite', array('cache' => true));
+
+ $cached = $this->Toolbar->readCache('sql_log');
+ $this->assertTrue(isset($cached['test_suite']));
+ $this->assertEqual($cached['test_suite'][0], $result[0]);
+ }
+/**
+ * reset the view paths
+ *
+ * @return void
+ **/
+ function endCase() {
+ App::build(array('views' => $this->_viewPaths), true);
+ Cache::delete('debug_kit_toolbar_test_case', 'default');
+ }
+/**
+ * endTest
+ *
+ * @access public
+ * @return void
+ */
+ function endTest() {
+ unset($this->Toolbar, $this->Controller);
+ ClassRegistry::removeObject('view');
+ ClassRegistry::flush();
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/groups/view_group.group.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/groups/view_group.group.php
new file mode 100644
index 000000000..4f5625545
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/groups/view_group.group.php
@@ -0,0 +1,44 @@
+autoRender = false;
+ return 'I am some value from requestAction.';
+ }
+
+ function request_action_render() {
+ $this->set('test', 'I have been rendered.');
+ }
+
+}
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/test_app/vendors/test_panel.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/test_app/vendors/test_panel.php
new file mode 100644
index 000000000..3b004d3f7
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/test_app/vendors/test_panel.php
@@ -0,0 +1,24 @@
+testPanel = true;
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/test_app/views/debug_kit_test/request_action_render.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/test_app/views/debug_kit_test/request_action_render.ctp
new file mode 100644
index 000000000..172d541d7
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/tests/test_app/views/debug_kit_test/request_action_render.ctp
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/debug_kit_debugger.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/debug_kit_debugger.php
new file mode 100644
index 000000000..862ce627d
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/debug_kit_debugger.php
@@ -0,0 +1,400 @@
+__benchmarks) {
+ return;
+ }
+ $timers = array_values(DebugKitDebugger::getTimers());
+ $end = end($timers);
+ echo '';
+ echo 'Debug timer info ';
+ echo 'Message Start Time (ms) End Time (ms) Duration (ms) ';
+ $i = 0;
+ foreach ($timers as $timer) {
+ $indent = 0;
+ for ($j = 0; $j < $i; $j++) {
+ if (($timers[$j]['end']) > ($timer['start']) && ($timers[$j]['end']) > ($timer['end'])) {
+ $indent++;
+ }
+ }
+ $indent = str_repeat(' » ', $indent);
+
+ extract($timer);
+ $start = round($start * 1000, 0);
+ $end = round($end * 1000, 0);
+ $time = round($time * 1000, 0);
+ echo "{$indent}$message $start $end $time ";
+ $i++;
+ }
+ echo '
';
+ }
+/**
+ * Start an benchmarking timer.
+ *
+ * @param string $name The name of the timer to start.
+ * @param string $message A message for your timer
+ * @return bool true
+ * @static
+ **/
+ function startTimer($name = null, $message = null) {
+ $start = getMicrotime();
+ $_this =& DebugKitDebugger::getInstance();
+
+ if (!$name) {
+ $named = false;
+ $calledFrom = debug_backtrace();
+ $_name = $name = Debugger::trimpath($calledFrom[0]['file']) . ' line ' . $calledFrom[0]['line'];
+ } else {
+ $named = true;
+ }
+
+ if (!$message) {
+ $message = $name;
+ }
+
+ $_name = $name;
+ $i = 1;
+ while (isset($_this->__benchmarks[$name])) {
+ $i++;
+ $name = $_name . ' #' . $i;
+ }
+
+ if ($i > 1) {
+ $message .= ' #' . $i;
+ }
+
+ $_this->__benchmarks[$name] = array(
+ 'start' => $start,
+ 'message' => $message,
+ 'named' => $named
+ );
+ return true;
+ }
+/**
+ * Stop a benchmarking timer.
+ *
+ * $name should be the same as the $name used in startTimer().
+ *
+ * @param string $name The name of the timer to end.
+ * @access public
+ * @return boolean true if timer was ended, false if timer was not started.
+ * @static
+ */
+ function stopTimer($name = null) {
+ $end = getMicrotime();
+ $_this =& DebugKitDebugger::getInstance();
+ if (!$name) {
+ $names = array_reverse(array_keys($_this->__benchmarks));
+ foreach($names as $name) {
+ if (!empty($_this->__benchmarks[$name]['end'])) {
+ continue;
+ }
+ if (empty($_this->__benchmarks[$name]['named'])) {
+ break;
+ }
+ }
+ } else {
+ $i = 1;
+ $_name = $name;
+ while (isset($_this->__benchmarks[$name])) {
+ if (empty($_this->__benchmarks[$name]['end'])) {
+ break;
+ }
+ $i++;
+ $name = $_name . ' #' . $i;
+ }
+ }
+ if (!isset($_this->__benchmarks[$name])) {
+ return false;
+ }
+ $_this->__benchmarks[$name]['end'] = $end;
+ return true;
+ }
+/**
+ * Get all timers that have been started and stopped.
+ * Calculates elapsed time for each timer. If clear is true, will delete existing timers
+ *
+ * @param bool $clear false
+ * @return array
+ * @access public
+ **/
+ function getTimers($clear = false) {
+ $_this =& DebugKitDebugger::getInstance();
+ $start = DebugKitDebugger::requestStartTime();
+ $now = getMicrotime();
+
+ $times = array();
+ if (!empty($_this->__benchmarks)) {
+ $firstTimer = current($_this->__benchmarks);
+ $_end = $firstTimer['start'];
+ } else {
+ $_end = $now;
+ }
+ $times['Core Processing (Derived)'] = array(
+ 'message' => __d('debug_kit', 'Core Processing (Derived)', true),
+ 'start' => 0,
+ 'end' => $_end - $start,
+ 'time' => round($_end - $start, 6),
+ 'named' => null
+ );
+ foreach ($_this->__benchmarks as $name => $timer) {
+ if (!isset($timer['end'])) {
+ $timer['end'] = $now;
+ }
+ $times[$name] = array_merge($timer, array(
+ 'start' => $timer['start'] - $start,
+ 'end' => $timer['end'] - $start,
+ 'time' => DebugKitDebugger::elapsedTime($name)
+ ));
+ }
+ if ($clear) {
+ $_this->__benchmarks = array();
+ }
+ return $times;
+ }
+/**
+ * Clear all existing timers
+ *
+ * @return bool true
+ **/
+ function clearTimers() {
+ $_this =& DebugKitDebugger::getInstance();
+ $_this->__benchmarks = array();
+ return true;
+ }
+/**
+ * Get the difference in time between the timer start and timer end.
+ *
+ * @param $name string the name of the timer you want elapsed time for.
+ * @param $precision int the number of decimal places to return, defaults to 5.
+ * @return float number of seconds elapsed for timer name, 0 on missing key
+ * @static
+ **/
+ function elapsedTime($name = 'default', $precision = 5) {
+ $_this =& DebugKitDebugger::getInstance();
+ if (!isset($_this->__benchmarks[$name]['start']) || !isset($_this->__benchmarks[$name]['end'])) {
+ return 0;
+ }
+ return round($_this->__benchmarks[$name]['end'] - $_this->__benchmarks[$name]['start'], $precision);
+ }
+/**
+ * Get the total execution time until this point
+ *
+ * @access public
+ * @return float elapsed time in seconds since script start.
+ * @static
+ */
+ function requestTime() {
+ $start = DebugKitDebugger::requestStartTime();
+ $now = getMicroTime();
+ return ($now - $start);
+ }
+/**
+ * get the time the current request started.
+ *
+ * @access public
+ * @return float time of request start
+ * @static
+ */
+ function requestStartTime() {
+ if (defined('TIME_START')) {
+ $startTime = TIME_START;
+ } else if (isset($GLOBALS['TIME_START'])) {
+ $startTime = $GLOBALS['TIME_START'];
+ } else {
+ $startTime = env('REQUEST_TIME');
+ }
+ return $startTime;
+ }
+/**
+ * get current memory usage
+ *
+ * @return integer number of bytes ram currently in use. 0 if memory_get_usage() is not available.
+ * @static
+ **/
+ function getMemoryUse() {
+ if (!function_exists('memory_get_usage')) {
+ return 0;
+ }
+ return memory_get_usage();
+ }
+/**
+ * Get peak memory use
+ *
+ * @return integer peak memory use (in bytes). Returns 0 if memory_get_peak_usage() is not available
+ * @static
+ **/
+ function getPeakMemoryUse() {
+ if (!function_exists('memory_get_peak_usage')) {
+ return 0;
+ }
+ return memory_get_peak_usage();
+ }
+/**
+ * Stores a memory point in the internal tracker.
+ * Takes a optional message name which can be used to identify the memory point.
+ * If no message is supplied a debug_backtrace will be done to identifty the memory point.
+ * If you don't have memory_get_xx methods this will not work.
+ *
+ * @param string $message Message to identify this memory point.
+ * @return boolean
+ **/
+ function setMemoryPoint($message = null) {
+ $memoryUse = DebugKitDebugger::getMemoryUse();
+ if (!$message) {
+ $named = false;
+ $trace = debug_backtrace();
+ $message = Debugger::trimpath($trace[0]['file']) . ' line ' . $trace[0]['line'];
+ }
+ $self =& DebugKitDebugger::getInstance();
+ if (isset($self->__memoryPoints[$message])) {
+ $originalMessage = $message;
+ $i = 1;
+ while (isset($self->__memoryPoints[$message])) {
+ $i++;
+ $message = $originalMessage . ' #' . $i;
+ }
+ }
+ $self->__memoryPoints[$message] = $memoryUse;
+ return true;
+ }
+/**
+ * Get all the stored memory points
+ *
+ * @param boolean $clear Whether you want to clear the memory points as well. Defaults to false.
+ * @return array Array of memory marks stored so far.
+ **/
+ function getMemoryPoints($clear = false) {
+ $self =& DebugKitDebugger::getInstance();
+ $marks = $self->__memoryPoints;
+ if ($clear) {
+ $self->__memoryPoints = array();
+ }
+ return $marks;
+ }
+/**
+ * Clear out any existing memory points
+ *
+ * @return void
+ **/
+ function clearMemoryPoints() {
+ $self =& DebugKitDebugger::getInstance();
+ $self->__memoryPoints = array();
+ }
+/**
+ * Handles object conversion to debug string.
+ *
+ * @param string $var Object to convert
+ * @access protected
+ */
+ function _output($data = array()) {
+ extract($data);
+ if (is_array($level)) {
+ $error = $level['error'];
+ $code = $level['code'];
+ if (isset($level['helpID'])) {
+ $helpID = $level['helpID'];
+ } else {
+ $helpID = '';
+ }
+ $description = $level['description'];
+ $file = $level['file'];
+ $line = $level['line'];
+ $context = $level['context'];
+ $level = $level['level'];
+ }
+ $files = $this->trace(array('start' => 2, 'format' => 'points'));
+ $listing = $this->excerpt($files[0]['file'], $files[0]['line'] - 1, 1);
+ $trace = $this->trace(array('start' => 2, 'depth' => '20'));
+
+ if ($this->_outputFormat == 'fb') {
+ $kontext = array();
+ foreach ((array)$context as $var => $value) {
+ $kontext[] = "\${$var}\t=\t" . $this->exportVar($value, 1);
+ }
+ $this->_fireError($error, $code, $description, $file, $line, $trace, $kontext);
+ } else {
+ $data = compact(
+ 'level', 'error', 'code', 'helpID', 'description', 'file', 'path', 'line', 'context'
+ );
+ echo parent::_output($data);
+ }
+ }
+/**
+ * Create a FirePHP error message
+ *
+ * @param string $error Name of error
+ * @param string $code Code of error
+ * @param string $description Description of error
+ * @param string $file File error occured in
+ * @param string $line Line error occured on
+ * @param string $trace Stack trace at time of error
+ * @param string $context context of error
+ * @return void
+ * @access protected
+ */
+ function _fireError($error, $code, $description, $file, $line, $trace, $context) {
+ $name = $error . ' - ' . $description;
+ $message = "$error $code $description on line: $line in file: $file";
+ FireCake::group($name);
+ FireCake::error($message, $name);
+ FireCake::log($context, 'Context');
+ FireCake::log($trace, 'Trace');
+ FireCake::groupEnd();
+ }
+}
+
+
+Debugger::invoke(DebugKitDebugger::getInstance('DebugKitDebugger'));
+Debugger::getInstance('DebugKitDebugger');
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/fire_cake.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/fire_cake.php
new file mode 100644
index 000000000..1b7835ccb
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/fire_cake.php
@@ -0,0 +1,546 @@
+ 10,
+ 'maxArrayDepth' => 20,
+ 'useNativeJsonEncode' => true,
+ 'includeLineNumbers' => true,
+ );
+/**
+ * Message Levels for messages sent via FirePHP
+ *
+ * @var array
+ */
+ var $_levels = array(
+ 'log' => 'LOG',
+ 'info' => 'INFO',
+ 'warn' => 'WARN',
+ 'error' => 'ERROR',
+ 'dump' => 'DUMP',
+ 'trace' => 'TRACE',
+ 'exception' => 'EXCEPTION',
+ 'table' => 'TABLE',
+ 'groupStart' => 'GROUP_START',
+ 'groupEnd' => 'GROUP_END',
+ );
+
+ var $_version = '0.2.1';
+/**
+ * internal messageIndex counter
+ *
+ * @var int
+ * @access protected
+ */
+ var $_messageIndex = 1;
+/**
+ * stack of objects encoded by stringEncode()
+ *
+ * @var array
+ **/
+ var $_encodedObjects = array();
+/**
+ * methodIndex to include in tracebacks when using includeLineNumbers
+ *
+ * @var array
+ **/
+ var $_methodIndex = array('info', 'log', 'warn', 'error', 'table', 'trace');
+/**
+ * FireCake output status
+ *
+ * @var bool
+ **/
+ var $_enabled = true;
+/**
+ * get Instance of the singleton
+ *
+ * @param string $class Class instance to store in the singleton. Used with subclasses and Tests.
+ * @access public
+ * @static
+ * @return void
+ */
+ function &getInstance($class = null) {
+ static $instance = array();
+ if (!empty($class)) {
+ if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) {
+ $instance[0] =& new $class();
+ $instance[0]->setOptions();
+ }
+ }
+ if (!isset($instance[0]) || !$instance[0]) {
+ $instance[0] =& new FireCake();
+ $instance[0]->setOptions();
+ }
+ return $instance[0];
+ }
+/**
+ * setOptions
+ *
+ * @param array $options Array of options to set.
+ * @access public
+ * @static
+ * @return void
+ */
+ function setOptions($options = array()) {
+ $_this =& FireCake::getInstance();
+ if (empty($_this->options)) {
+ $_this->options = array_merge($_this->_defaultOptions, $options);
+ } else {
+ $_this->options = array_merge($_this->options, $options);
+ }
+ }
+/**
+ * Return boolean based on presence of FirePHP extension
+ *
+ * @access public
+ * @return boolean
+ **/
+ function detectClientExtension() {
+ $ua = FireCake::getUserAgent();
+ if (!preg_match('/\sFirePHP\/([\.|\d]*)\s?/si', $ua, $match) || !version_compare($match[1], '0.0.6', '>=')) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * Get the Current UserAgent
+ *
+ * @access public
+ * @static
+ * @return string UserAgent string of active client connection
+ **/
+ function getUserAgent() {
+ return env('HTTP_USER_AGENT');
+ }
+/**
+ * Disable FireCake output
+ * All subsequent output calls will not be run.
+ *
+ * @return void
+ **/
+ function disable() {
+ $_this =& FireCake::getInstance();
+ $_this->_enabled = false;
+ }
+/**
+ * Enable FireCake output
+ *
+ * @return void
+ **/
+ function enable() {
+ $_this =& FireCake::getInstance();
+ $_this->_enabled = true;
+ }
+/**
+ * Convenience wrapper for LOG messages
+ *
+ * @param string $message Message to log
+ * @param string $label Label for message (optional)
+ * @access public
+ * @static
+ * @return void
+ */
+ function log($message, $label = null) {
+ FireCake::fb($message, $label, 'log');
+ }
+/**
+ * Convenience wrapper for WARN messages
+ *
+ * @param string $message Message to log
+ * @param string $label Label for message (optional)
+ * @access public
+ * @static
+ * @return void
+ */
+ function warn($message, $label = null) {
+ FireCake::fb($message, $label, 'warn');
+ }
+/**
+ * Convenience wrapper for INFO messages
+ *
+ * @param string $message Message to log
+ * @param string $label Label for message (optional)
+ * @access public
+ * @static
+ * @return void
+ */
+ function info($message, $label = null) {
+ FireCake::fb($message, $label, 'info');
+ }
+/**
+ * Convenience wrapper for ERROR messages
+ *
+ * @param string $message Message to log
+ * @param string $label Label for message (optional)
+ * @access public
+ * @static
+ * @return void
+ */
+ function error($message, $label = null) {
+ FireCake::fb($message, $label, 'error');
+ }
+/**
+ * Convenience wrapper for TABLE messages
+ *
+ * @param string $message Message to log
+ * @param string $label Label for message (optional)
+ * @access public
+ * @static
+ * @return void
+ */
+ function table($label, $message) {
+ FireCake::fb($message, $label, 'table');
+ }
+/**
+ * Convenience wrapper for DUMP messages
+ *
+ * @param string $message Message to log
+ * @param string $label Unique label for message
+ * @access public
+ * @static
+ * @return void
+ */
+ function dump($label, $message) {
+ FireCake::fb($message, $label, 'dump');
+ }
+/**
+ * Convenience wrapper for TRACE messages
+ *
+ * @param string $label Label for message (optional)
+ * @access public
+ * @return void
+ */
+ function trace($label) {
+ FireCake::fb($label, 'trace');
+ }
+/**
+ * Convenience wrapper for GROUP messages
+ * Messages following the group call will be nested in a group block
+ *
+ * @param string $label Label for group (optional)
+ * @access public
+ * @return void
+ */
+ function group($label) {
+ FireCake::fb(null, $label, 'groupStart');
+ }
+/**
+ * Convenience wrapper for GROUPEND messages
+ * Closes a group block
+ *
+ * @param string $label Label for group (optional)
+ * @access public
+ * @return void
+ */
+ function groupEnd() {
+ FireCake::fb(null, null, 'groupEnd');
+ }
+/**
+ * fb - Send messages with FireCake to FirePHP
+ *
+ * Much like FirePHP's fb() this method can be called with various parameter counts
+ * fb($message) - Just send a message defaults to LOG type
+ * fb($message, $type) - Send a message with a specific type
+ * fb($message, $label, $type) - Send a message with a custom label and type.
+ *
+ * @param mixed $message Message to output. For other parameters see usage above.
+ * @static
+ * @return void
+ **/
+ function fb($message) {
+ $_this =& FireCake::getInstance();
+
+ if (headers_sent($filename, $linenum)) {
+ trigger_error(sprintf(__d('debug_kit', 'Headers already sent in %s on line %s. Cannot send log data to FirePHP.', true), $filename, $linenum), E_USER_WARNING);
+ return false;
+ }
+ if (!$_this->_enabled || !$_this->detectClientExtension()) {
+ return false;
+ }
+
+ $args = func_get_args();
+ $type = $label = null;
+ switch (count($args)) {
+ case 1:
+ $type = $_this->_levels['log'];
+ break;
+ case 2:
+ $type = $args[1];
+ break;
+ case 3:
+ $type = $args[2];
+ $label = $args[1];
+ break;
+ default:
+ trigger_error(__d('debug_kit', 'Incorrect parameter count for FireCake::fb()', true), E_USER_WARNING);
+ return false;
+ }
+ if (isset($_this->_levels[$type])) {
+ $type = $_this->_levels[$type];
+ } else {
+ $type = $_this->_levels['log'];
+ }
+
+ $meta = array();
+ $skipFinalObjectEncode = false;
+ if ($type == $_this->_levels['trace']) {
+ $trace = debug_backtrace();
+ if (!$trace) {
+ return false;
+ }
+ $message = $_this->_parseTrace($trace, $args[0]);
+ $skipFinalObjectEncode = true;
+ }
+
+ if ($_this->options['includeLineNumbers']) {
+ if (!isset($meta['file']) || !isset($meta['line'])) {
+ $trace = debug_backtrace();
+ for ($i = 0, $len = count($trace); $i < $len ; $i++) {
+ $keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
+ $selfCall = ($keySet &&
+ strtolower($trace[$i]['class']) == 'firecake' &&
+ in_array($trace[$i]['function'], $_this->_methodIndex)
+ );
+ if ($selfCall) {
+ $meta['File'] = isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '';
+ $meta['Line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : '';
+ break;
+ }
+ }
+ }
+ }
+
+ $structureIndex = 1;
+ if ($type == $_this->_levels['dump']) {
+ $structureIndex = 2;
+ $_this->_sendHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
+ } else {
+ $_this->_sendHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
+ }
+
+ $_this->_sendHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
+ $_this->_sendHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'. $_this->_version);
+ if ($type == $_this->_levels['groupStart']) {
+ $meta['Collapsed'] = 'true';
+ }
+ if ($type == $_this->_levels['dump']) {
+ $dump = $_this->jsonEncode($message);
+ $msg = '{"' . $label .'":' . $dump .'}';
+ } else {
+ $meta['Type'] = $type;
+ if ($label !== null) {
+ $meta['Label'] = $label;
+ }
+ $msg = '[' . $_this->jsonEncode($meta) . ',' . $_this->jsonEncode($message, $skipFinalObjectEncode).']';
+ }
+
+ $lines = explode("\n", chunk_split($msg, 5000, "\n"));
+
+ foreach ($lines as $i => $line) {
+ if (empty($line)) {
+ continue;
+ }
+ $header = 'X-Wf-1-' . $structureIndex . '-1-' . $_this->_messageIndex;
+ if (count($lines) > 2) {
+ $first = ($i == 0) ? strlen($msg) : '';
+ $end = ($i < count($lines) - 2) ? '\\' : '';
+ $message = $first . '|' . $line . '|' . $end;
+ $_this->_sendHeader($header, $message);
+ } else {
+ $_this->_sendHeader($header, strlen($line) . '|' . $line . '|');
+ }
+ $_this->_messageIndex++;
+ if ($_this->_messageIndex > 99999) {
+ trigger_error(__d('debug_kit', 'Maximum number (99,999) of messages reached!', true), E_USER_WARNING);
+ }
+ }
+ $_this->_sendHeader('X-Wf-1-Index', $_this->_messageIndex - 1);
+ return true;
+ }
+/**
+ * Parse a debug backtrace
+ *
+ * @param array $trace Debug backtrace output
+ * @access protected
+ * @return array
+ **/
+ function _parseTrace($trace, $messageName) {
+ $message = array();
+ for ($i = 0, $len = count($trace); $i < $len ; $i++) {
+ $keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
+ $selfCall = ($keySet && $trace[$i]['class'] == 'FireCake');
+ if (!$selfCall) {
+ $message = array(
+ 'Class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : '',
+ 'Type' => isset($trace[$i]['type']) ? $trace[$i]['type'] : '',
+ 'Function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : '',
+ 'Message' => $messageName,
+ 'File' => isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '',
+ 'Line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : '',
+ 'Args' => isset($trace[$i]['args']) ? $this->stringEncode($trace[$i]['args']) : '',
+ 'Trace' => $this->_escapeTrace(array_splice($trace, $i + 1))
+ );
+ break;
+ }
+ }
+ return $message;
+ }
+/**
+ * Fix a trace for use in output
+ *
+ * @param mixed $trace Trace to fix
+ * @access protected
+ * @static
+ * @return string
+ **/
+ function _escapeTrace($trace) {
+ for ($i = 0, $len = count($trace); $i < $len; $i++) {
+ if (isset($trace[$i]['file'])) {
+ $trace[$i]['file'] = Debugger::trimPath($trace[$i]['file']);
+ }
+ if (isset($trace[$i]['args'])) {
+ $trace[$i]['args'] = $this->stringEncode($trace[$i]['args']);
+ }
+ }
+ return $trace;
+ }
+/**
+ * Encode non string objects to string.
+ * Filter out recursion, so no errors are raised by json_encode or $javascript->object()
+ *
+ * @param mixed $object Object or variable to encode to string.
+ * @param int $objectDepth Current Depth in object chains.
+ * @param int $arrayDepth Current Depth in array chains.
+ * @static
+ * @return void
+ **/
+ function stringEncode($object, $objectDepth = 1, $arrayDepth = 1) {
+ $_this =& FireCake::getInstance();
+ $return = array();
+ if (is_resource($object)) {
+ return '** ' . (string)$object . '**';
+ }
+ if (is_object($object)) {
+ if ($objectDepth == $_this->options['maxObjectDepth']) {
+ return '** Max Object Depth (' . $_this->options['maxObjectDepth'] . ') **';
+ }
+ foreach ($_this->_encodedObjects as $encoded) {
+ if ($encoded === $object) {
+ return '** Recursion (' . get_class($object) . ') **';
+ }
+ }
+ $_this->_encodedObjects[] =& $object;
+
+ $return['__className'] = $class = get_class($object);
+ $properties = (array)$object;
+ foreach ($properties as $name => $property) {
+ $return[$name] = FireCake::stringEncode($property, 1, $objectDepth + 1);
+ }
+ array_pop($_this->_encodedObjects);
+ }
+ if (is_array($object)) {
+ if ($arrayDepth == $_this->options['maxArrayDepth']) {
+ return '** Max Array Depth ('. $_this->options['maxArrayDepth'] . ') **';
+ }
+ foreach ($object as $key => $value) {
+ $return[$key] = FireCake::stringEncode($value, 1, $arrayDepth + 1);
+ }
+ }
+ if (is_string($object) || is_numeric($object) || is_bool($object) || is_null($object)) {
+ return $object;
+ }
+ return $return;
+ }
+/**
+ * Encode an object into JSON
+ *
+ * @param mixed $object Object or array to json encode
+ * @param boolean $doIt
+ * @access public
+ * @static
+ * @return string
+ **/
+ function jsonEncode($object, $skipEncode = false) {
+ $_this =& FireCake::getInstance();
+ if (!$skipEncode) {
+ $object = FireCake::stringEncode($object);
+ }
+
+ if (function_exists('json_encode') && $_this->options['useNativeJsonEncode']) {
+ return json_encode($object);
+ } else {
+ return FireCake::_jsonEncode($object);
+ }
+ }
+/**
+ * jsonEncode Helper method for PHP4 compatibility
+ *
+ * @param mixed $object Something to encode
+ * @access protected
+ * @static
+ * @return string
+ **/
+ function _jsonEncode($object) {
+ if (!class_exists('JavascriptHelper')) {
+ App::import('Helper', 'Javascript');
+ }
+ $javascript =& new JavascriptHelper();
+ $javascript->useNative = false;
+ if (is_string($object)) {
+ return '"' . $javascript->escapeString($object) . '"';
+ }
+ return $javascript->object($object);
+ }
+/**
+ * Send Headers - write headers.
+ *
+ * @access protected
+ * @return void
+ **/
+ function _sendHeader($name, $value) {
+ header($name . ': ' . $value);
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/shells/benchmark.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/shells/benchmark.php
new file mode 100644
index 000000000..eb2a3dcc4
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/shells/benchmark.php
@@ -0,0 +1,167 @@
+args) || count($this->args) > 1) {
+ return $this->help();
+ }
+
+ $url = $this->args[0];
+ $defaults = array('t' => 100, 'n' => 10);
+ $options = array_merge($defaults, $this->params);
+ $times = array();
+
+ $this->out(String::insert(__d('debug_kit', '-> Testing :url', true), compact('url')));
+ $this->out("");
+ for ($i = 0; $i < $options['n']; $i++) {
+ if (floor($options['t'] - array_sum($times)) <= 0 || $options['n'] <= 1) {
+ break;
+ }
+
+ $start = microtime(true);
+ file_get_contents($url);
+ $stop = microtime(true);
+
+ $times[] = $stop - $start;
+ }
+ $this->_results($times);
+ }
+/**
+ * Prints calculated results
+ *
+ * @param array $times Array of time values
+ * @return void
+ * @access protected
+ */
+ function _results($times) {
+ $duration = array_sum($times);
+ $requests = count($times);
+
+ $this->out(String::insert(__d('debug_kit', 'Total Requests made: :requests', true), compact('requests')));
+ $this->out(String::insert(__d('debug_kit', 'Total Time elapsed: :duration (seconds)', true), compact('duration')));
+
+ $this->out("");
+
+ $this->out(String::insert(__d('debug_kit', 'Requests/Second: :rps req/sec', true), array(
+ 'rps' => round($requests / $duration, 3)
+ )));
+
+ $this->out(String::insert(__d('debug_kit', 'Average request time: :average-time seconds', true), array(
+ 'average-time' => round($duration / $requests, 3)
+ )));
+
+ $this->out(String::insert(__d('debug_kit', 'Standard deviation of average request time: :std-dev', true), array(
+ 'std-dev' => round($this->_deviation($times, true), 3)
+ )));
+
+ $this->out(String::insert(__d('debug_kit', 'Longest/shortest request: :longest sec/:shortest sec', true), array(
+ 'longest' => round(max($times), 3),
+ 'shortest' => round(min($times), 3)
+ )));
+
+ $this->out("");
+
+ }
+/**
+ * One-pass, numerically stable calculation of population variance.
+ *
+ * Donald E. Knuth (1998).
+ * The Art of Computer Programming, volume 2: Seminumerical Algorithms, 3rd edn.,
+ * p. 232. Boston: Addison-Wesley.
+ *
+ * @param array $times Array of values
+ * @param boolean $sample If true, calculates an unbiased estimate of the population
+ * variance from a finite sample.
+ * @return float Variance
+ * @access protected
+ */
+ function _variance($times, $sample = true) {
+ $n = $mean = $M2 = 0;
+
+ foreach($times as $time){
+ $n += 1;
+ $delta = $time - $mean;
+ $mean = $mean + $delta/$n;
+ $M2 = $M2 + $delta*($time - $mean);
+ }
+
+ if ($sample) $n -= 1;
+
+ return $M2/$n;
+ }
+/**
+ * Calculate the standard deviation.
+ *
+ * @param array $times Array of values
+ * @return float Standard deviation
+ * @access protected
+ */
+ function _deviation($times, $sample = true) {
+ return sqrt($this->_variance($times, $sample));
+ }
+/**
+ * Help for Benchmark shell
+ *
+ * @return void
+ * @access public
+ */
+ function help() {
+ $this->out(__d('debug_kit', "DebugKit Benchmark Shell", true));
+ $this->out("");
+ $this->out(__d('debug_kit', "\tAllows you to obtain some rough benchmarking statistics \n\tabout a fully qualified URL.", true));
+ $this->out("");
+ $this->out(__d('debug_kit', "\tUse:", true));
+ $this->out(__d('debug_kit', "\t\tcake benchmark [-n iterations] [-t timeout] url", true));
+ $this->out("");
+ $this->out(__d('debug_kit', "\tParams:", true));
+ $this->out(__d('debug_kit', "\t\t-n Number of iterations to perform. Defaults to 10. \n\t\t Must be an integer.", true));
+ $this->out(__d('debug_kit', "\t\t-t Maximum total time for all iterations, in seconds. \n\t\t Defaults to 100. Must be an integer.", true));
+ $this->out("");
+ $this->out(__d('debug_kit', "\tIf a single iteration takes more than the \n\ttimeout specified, only one request will be made.", true));
+ $this->out("");
+ $this->out(__d('debug_kit', "\tExample Use:", true));
+ $this->out(__d('debug_kit', "\t\tcake benchmark -n 10 -t 100 http://localhost/testsite", true));
+ $this->out("");
+ $this->out(__d('debug_kit', "\tNote that this benchmark does not include browser render time", true));
+ $this->out("");
+ $this->hr();
+ $this->out("");
+ }
+}
+
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/shells/whitespace.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/shells/whitespace.php
new file mode 100644
index 000000000..d5185d454
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/vendors/shells/whitespace.php
@@ -0,0 +1,69 @@
+findRecursive('.*\.php');
+ $this->out("Checking *.php in ".ROOT);
+ foreach($r as $file) {
+ $c = file_get_contents($file);
+ if (preg_match('/^[\n\r|\n\r|\n|\r|\s]+\<\?php/',$c)) {
+ $this->out('!!!contains leading whitespaces: '.$this->shortPath($file));
+ }
+ if (preg_match('/\?\>[\n\r|\n\r|\n|\r|\s]+$/',$c)) {
+ $this->out('!!!contains trailing whitespaces: '.$this->shortPath($file));
+ }
+ }
+ }
+
+/**
+ * Much like main() except files are modified. Be sure to have
+ * backups or use version control.
+ *
+ * @return void
+ */
+ function trim() {
+ $siteRoot = new Folder(ROOT);
+
+ $r = $siteRoot->findRecursive('.*\.php');
+ $this->out("Checking *.php in ".ROOT);
+ foreach($r as $file) {
+ $c = file_get_contents($file);
+ if (preg_match('/^[\n\r|\n\r|\n|\r|\s]+\<\?php/', $c) || preg_match('/\?\>[\n\r|\n\r|\n|\r|\s]+$/', $c)) {
+ $this->out('trimming' . $this->shortPath($file));
+ $c = preg_replace('/^[\n\r|\n\r|\n|\r|\s]+\<\?php/', '[\n\r|\n\r|\n|\r|\s]+$/', '?>', $c);
+ file_put_contents($file, $c);
+ }
+ }
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/debug.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/debug.php
new file mode 100644
index 000000000..43601e72d
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/debug.php
@@ -0,0 +1,100 @@
+params['url']['ext']) && $this->params['url']['ext'] === 'html') ||
+ !isset($this->params['url']['ext'])
+ );
+ if ($isHtml) {
+ $out .= sprintf("\n", __d('debug_kit', 'Starting to render', true), $name);
+ }
+ $out .= parent::element($name, $params, $loadHelpers);
+ if ($isHtml) {
+ $out .= sprintf("\n\n", __d('debug_kit', 'Finished', true), $name);
+ }
+ return $out;
+ }
+
+/**
+ * Renders view for given action and layout. If $file is given, that is used
+ * for a view filename (e.g. customFunkyView.ctp).
+ * Adds timers, for all subsequent rendering, and injects the debugKit toolbar.
+ *
+ * @param string $action Name of action to render for
+ * @param string $layout Layout to use
+ * @param string $file Custom filename for view
+ * @return string Rendered Element
+ */
+ function render($action = null, $layout = null, $file = null) {
+ DebugKitDebugger::startTimer('viewRender', __d('debug_kit', 'Rendering View', true));
+
+ $out = parent::render($action, $layout, $file);
+
+ DebugKitDebugger::stopTimer('viewRender');
+ DebugKitDebugger::stopTimer('controllerRender');
+ DebugKitDebugger::setMemoryPoint(__d('debug_kit', 'View render complete', true));
+
+ if (empty($this->params['requested']) && isset($this->loaded['toolbar'])) {
+ $backend = $this->loaded['toolbar']->getName();
+ $this->loaded['toolbar']->{$backend}->send();
+ }
+ if (empty($this->output)) {
+ return $out;
+ }
+ return $this->output;
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/debug_toolbar.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/debug_toolbar.ctp
new file mode 100644
index 000000000..327f0eb85
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/debug_toolbar.ctp
@@ -0,0 +1,58 @@
+
+
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/history_panel.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/history_panel.ctp
new file mode 100644
index 000000000..8f4cdab4d
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/history_panel.ctp
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+ link(__d('debug_kit', 'Restore to current request', true),
+ '#', array('class' => 'history-link', 'id' => 'history-restore-current')); ?>
+
+
+ link($previous['title'], $previous['url'], array('class' => 'history-link')); ?>
+
+
+
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/log_panel.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/log_panel.ctp
new file mode 100644
index 000000000..ae8a406e2
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/log_panel.ctp
@@ -0,0 +1,40 @@
+
+
+
+ $logs): ?>
+
+ 0):
+ $headers = array(__d('debug_kit', 'Time', true), __d('debug_kit', 'Message', true));
+ $rows = array();
+ for ($i = 0; $i < $len; $i += 2):
+ $rows[] = array(
+ $logs[$i][0], h($logs[$i][1])
+ );
+ endfor;
+ echo $toolbar->table($rows, $headers, array('title' => $logName));
+ else: ?>
+
+
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/request_panel.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/request_panel.ctp
new file mode 100644
index 000000000..310090ea9
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/request_panel.ctp
@@ -0,0 +1,36 @@
+
+
+Cake Params
+makeNeatArray($content['params']); ?>
+
+$_GET
+makeNeatArray($content['get']); ?>
+
+Cookie
+
+ makeNeatArray($content['cookie']); ?>
+
+ To view Cookies, add CookieComponent to Controller
+
+
+
+makeNeatArray($content['currentRoute']); ?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/session_panel.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/session_panel.ctp
new file mode 100644
index 000000000..c729a8273
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/session_panel.ctp
@@ -0,0 +1,22 @@
+
+
+makeNeatArray($content); ?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/sql_log_panel.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/sql_log_panel.ctp
new file mode 100755
index 000000000..148c694dc
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/sql_log_panel.ctp
@@ -0,0 +1,105 @@
+readCache('sql_log', $this->params['pass'][0]);
+}
+?>
+
+
+ $explain): ?>
+
+
+ getQueryLogs($dbName, array(
+ 'explain' => $explain, 'threshold' => $content['threshold']
+ ));
+ else:
+ $queryLog = $content[$dbName];
+ endif;
+ echo $toolbar->table($queryLog, $headers, array('title' => 'SQL Log ' . $dbName));
+ ?>
+
+
+
+
+message('Warning', __d('debug_kit', 'No active database connections', true));
+endif; ?>
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/timer_panel.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/timer_panel.ctp
new file mode 100644
index 000000000..c5c010937
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/timer_panel.ctp
@@ -0,0 +1,108 @@
+readCache('timer', $this->params['pass'][0]);
+ if (is_array($content)):
+ extract($content);
+ endif;
+endif;
+?>
+
+
+
+ message(__d('debug_kit', 'Peak Memory Use', true), $number->toReadableSize($peakMemory)); ?>
+
+
+ $value):
+ $rows[] = array($key, $number->toReadableSize($value));
+ endforeach;
+
+ echo $toolbar->table($rows, $headers);
+ ?>
+
+
+
+
+
+ precision($requestTime * 1000, 0)); ?>
+ message(__d('debug_kit', 'Total Request Time:', true), $totalTime)?>
+
+ $timeInfo):
+ $indent = 0;
+ for ($j = 0; $j < $i; $j++) {
+ if (($values[$j]['end'] > $timeInfo['start']) && ($values[$j]['end']) > ($timeInfo['end'])) {
+ $indent++;
+ }
+ }
+ $indent = str_repeat(' » ', $indent);
+ $rows[] = array(
+ $indent . $timeInfo['message'],
+ $number->precision($timeInfo['time'] * 1000, 2),
+ $simpleGraph->bar(
+ $number->precision($timeInfo['time'] * 1000, 2),
+ $number->precision($timeInfo['start'] * 1000, 2),
+ array(
+ 'max' => $maxTime * 1000,
+ 'requestTime' => $requestTime * 1000,
+ )
+ )
+ );
+ $i++;
+endforeach;
+
+if (strtolower($toolbar->getName()) == 'firephptoolbar'):
+ for ($i = 0, $len = count($rows); $i < $len; $i++):
+ unset($rows[$i][2]);
+ endfor;
+ unset($headers[2]);
+endif;
+
+echo $toolbar->table($rows, $headers, array('title' => 'Timers'));
+
+if (!isset($debugKitInHistoryMode)):
+ $toolbar->writeCache('timer', compact('timers', 'currentMemory', 'peakMemory', 'requestTime'));
+endif;
+?>
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/variables_panel.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/variables_panel.ctp
new file mode 100644
index 000000000..3be537d6a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/elements/variables_panel.ctp
@@ -0,0 +1,25 @@
+
+
+validationErrors'] = $this->validationErrors;
+$content['Loaded Helpers'] = array_keys($this->loaded);
+echo $toolbar->makeNeatArray($content); ?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/fire_php_toolbar.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/fire_php_toolbar.php
new file mode 100644
index 000000000..e8bb814af
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/fire_php_toolbar.php
@@ -0,0 +1,99 @@
+ 'firePHP', 'forceEnable' => false);
+/**
+ * send method
+ *
+ * @return void
+ * @access protected
+ */
+ function send() {
+ $view =& ClassRegistry::getObject('view');
+ $view->element('debug_toolbar', array('plugin' => 'debug_kit', 'disableTimer' => true));
+ }
+/**
+ * makeNeatArray.
+ *
+ * wraps FireCake::dump() allowing panel elements to continue functioning
+ *
+ * @param string $values
+ * @return void
+ */
+ function makeNeatArray($values) {
+ FireCake::info($values);
+ }
+/**
+ * Create a simple message
+ *
+ * @param string $label Label of message
+ * @param string $message Message content
+ * @return void
+ */
+ function message($label, $message) {
+ FireCake::log($message, $label);
+ }
+/**
+ * Generate a table with FireCake
+ *
+ * @param array $rows Rows to print
+ * @param array $headers Headers for table
+ * @param array $options Additional options and params
+ * @return void
+ */
+ function table($rows, $headers, $options = array()) {
+ $title = $headers[0];
+ if (isset($options['title'])) {
+ $title = $options['title'];
+ }
+ foreach ($rows as $i => $row) {
+ $rows[$i] = array_values($row);
+ }
+ array_unshift($rows, $headers);
+ FireCake::table($title, $rows);
+ }
+/**
+ * Start a panel which is a 'Group' in FirePHP
+ *
+ * @return void
+ **/
+ function panelStart($title, $anchor) {
+ FireCake::group($title);
+ }
+/**
+ * End a panel (Group)
+ *
+ * @return void
+ **/
+ function panelEnd() {
+ FireCake::groupEnd();
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/html_toolbar.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/html_toolbar.php
new file mode 100755
index 000000000..f772870ce
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/html_toolbar.php
@@ -0,0 +1,191 @@
+ 'html', 'forceEnable' => false);
+/**
+ * Recursively goes through an array and makes neat HTML out of it.
+ *
+ * @param mixed $values Array to make pretty.
+ * @param int $openDepth Depth to add open class
+ * @param int $currentDepth current depth.
+ * @return string
+ **/
+ function makeNeatArray($values, $openDepth = 0, $currentDepth = 0) {
+ $className ="neat-array depth-$currentDepth";
+ if ($openDepth > $currentDepth) {
+ $className .= ' expanded';
+ }
+ $nextDepth = $currentDepth + 1;
+ $out = "";
+ if (!is_array($values)) {
+ if (is_bool($values)) {
+ $values = array($values);
+ }
+ if (is_null($values)) {
+ $values = array(null);
+ }
+ }
+ if (empty($values)) {
+ $values[] = '(empty)';
+ }
+ foreach ($values as $key => $value) {
+ $out .= '' . $key . ' ';
+ if ($value === null) {
+ $value = '(null)';
+ }
+ if ($value === false) {
+ $value = '(false)';
+ }
+ if ($value === true) {
+ $value = '(true)';
+ }
+ if (empty($value) && $value != 0) {
+ $value = '(empty)';
+ }
+
+ if (is_object($value)) {
+ $value = Set::reverse($value, true);
+ }
+
+ if (is_array($value) && !empty($value)) {
+ $out .= $this->makeNeatArray($value, $openDepth, $nextDepth);
+ } else {
+ $out .= h($value);
+ }
+ $out .= ' ';
+ }
+ $out .= ' ';
+ return $out;
+ }
+/**
+ * Create an HTML message
+ *
+ * @param string $label label content
+ * @param string $message message content
+ * @return string
+ */
+ function message($label, $message) {
+ return sprintf('%s %s
', $label, $message);
+ }
+/**
+ * Start a panel.
+ * make a link and anchor.
+ *
+ * @return void
+ **/
+ function panelStart($title, $anchor) {
+ $link = $this->Html->link($title, '#' . $anchor);
+ return $link;
+ }
+/**
+ * Create a table.
+ *
+ * @param array $rows Rows to make.
+ * @param array $headers Optional header row.
+ * @return string
+ */
+ function table($rows, $headers = array()) {
+ $out = '';
+ if (!empty($headers)) {
+ $out .= $this->Html->tableHeaders($headers);
+ }
+ $out .= $this->Html->tableCells($rows, array('class' => 'odd'), array('class' => 'even'), false, false);
+ $out .= '
';
+ return $out;
+ }
+/**
+ * send method
+ *
+ * @return void
+ * @access public
+ */
+ function send() {
+ if (!$this->settings['forceEnable'] && Configure::read('debug') == 0) {
+ return;
+ }
+ $view =& ClassRegistry::getObject('view');
+ $head = $this->Html->css('/debug_kit/css/debug_toolbar');
+ if (isset($view->viewVars['debugToolbarJavascript'])) {
+ foreach ($view->viewVars['debugToolbarJavascript'] as $script) {
+ if ($script) {
+ $head .= $this->Html->script($script);
+ }
+ }
+ }
+ if (preg_match('##', $view->output)) {
+ $view->output = preg_replace('##', $head . "\n", $view->output, 1);
+ }
+ $toolbar = $view->element('debug_toolbar', array('plugin' => 'debug_kit', 'disableTimer' => true));
+ if (preg_match('# \n";
+ print "$test_name \n";
+ flush();
+ }
+
+ /**
+ * Send the headers necessary to ensure the page is
+ * reloaded on every request. Otherwise you could be
+ * scratching your head over out of date test data.
+ * @access public
+ */
+ static function sendNoCacheHeaders() {
+ if (! headers_sent()) {
+ header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: post-check=0, pre-check=0", false);
+ header("Pragma: no-cache");
+ }
+ }
+
+ /**
+ * Paints the CSS. Add additional styles here.
+ * @return string CSS code as text.
+ * @access protected
+ */
+ protected function getCss() {
+ return ".fail { background-color: inherit; color: red; }" .
+ ".pass { background-color: inherit; color: green; }" .
+ " pre { background-color: lightgray; color: inherit; }";
+ }
+
+ /**
+ * Paints the end of the test with a summary of
+ * the passes and failures.
+ * @param string $test_name Name class of test.
+ * @access public
+ */
+ function paintFooter($test_name) {
+ $colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
+ print "";
+ print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
+ print " test cases complete:\n";
+ print "" . $this->getPassCount() . " passes, ";
+ print "" . $this->getFailCount() . " fails and ";
+ print "" . $this->getExceptionCount() . " exceptions.";
+ print "
\n";
+ print "#', $view->output)) {
+ $view->output = preg_replace('##', $toolbar . "\n", $view->output, 1);
+ }
+ }
+/**
+ * Generates a SQL explain link for a given query
+ *
+ * @param string $sql SQL query string you want an explain link for.
+ * @return string Rendered Html link or '' if the query is not a select/describe
+ */
+ function explainLink($sql, $connection) {
+ if (!preg_match('/^(SELECT)/i', $sql)) {
+ return '';
+ }
+ App::import('Core', 'Security');
+ $hash = Security::hash($sql . $connection, null, true);
+ $url = array(
+ 'plugin' => 'debug_kit',
+ 'controller' => 'toolbar_access',
+ 'action' => 'sql_explain'
+ );
+ foreach (Router::prefixes() as $prefix) {
+ $url[$prefix] = false;
+ }
+ $this->explainLinkUid = (isset($this->explainLinkUid) ? $this->explainLinkUid + 1 : 0);
+ $uid = $this->explainLinkUid . '_' . rand(0, 10000);
+ $form = $this->Form->create('log', array('url' => $url, 'id' => "logForm{$uid}"));
+ $form .= $this->Form->hidden('log.ds', array('id' => "logDs{$uid}", 'value' => $connection));
+ $form .= $this->Form->hidden('log.sql', array('id' => "logSql{$uid}", 'value' => $sql));
+ $form .= $this->Form->hidden('log.hash', array('id' => "logHash{$uid}", 'value' => $hash));
+ $form .= $this->Form->submit(__d('debug_kit', 'Explain', true), array(
+ 'div' => false,
+ 'class' => 'sql-explain-link'
+ ));
+ $form .= $this->Form->end();
+ return $form;
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/simple_graph.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/simple_graph.php
new file mode 100644
index 000000000..22c17865c
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/simple_graph.php
@@ -0,0 +1,84 @@
+ (int) Maximum value in the graphs
+ * - width => (int)
+ * - valueType => string (value, percentage)
+ * - style => array
+ *
+ * @var array
+ */
+ var $__defaultSettings = array(
+ 'max' => 100,
+ 'width' => 350,
+ 'valueType' => 'value',
+ );
+/**
+ * bar method
+ *
+ * @param $value Value to be graphed
+ * @param $offset how much indentation
+ * @param $options Graph options
+ * @return string Html graph
+ * @access public
+ */
+ function bar($value, $offset, $options = array()) {
+ $settings = array_merge($this->__defaultSettings, $options);
+ extract($settings);
+
+ $graphValue = ($value / $max) * $width;
+ $graphValue = max(round($graphValue), 1);
+
+ if ($valueType == 'percentage') {
+ $graphOffset = 0;
+ } else {
+ $graphOffset = ($offset / $max) * $width;
+ $graphOffset = round($graphOffset);
+ }
+ return $this->Html->div(
+ 'debug-kit-graph-bar',
+ $this->Html->div(
+ 'debug-kit-graph-bar-value',
+ ' ',
+ array(
+ 'style' => "margin-left: {$graphOffset}px; width: {$graphValue}px",
+ 'title' => sprintf(__d('debug_kit', "Starting %sms into the request, taking %sms", true), $offset, $value),
+ )
+ ),
+ array('style' => "width: {$width}px;"),
+ false
+ );
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/toolbar.php b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/toolbar.php
new file mode 100644
index 000000000..1ae3a9734
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/helpers/toolbar.php
@@ -0,0 +1,182 @@
+_myName = strtolower(get_class($this));
+ $this->settings = am($this->settings, $options);
+
+ if ($this->_myName !== 'toolbarhelper') {
+ return;
+ }
+
+ if (!isset($options['output'])) {
+ $options['output'] = 'DebugKit.HtmlToolbar';
+ }
+ App::import('Helper', $options['output']);
+ $className = $options['output'];
+ if (strpos($options['output'], '.') !== false) {
+ list($plugin, $className) = explode('.', $options['output']);
+ }
+ $this->_backEndClassName = $className;
+ $this->helpers[$options['output']] = $options;
+ if (isset($options['cacheKey']) && isset($options['cacheConfig'])) {
+ $this->_cacheKey = $options['cacheKey'];
+ $this->_cacheConfig = $options['cacheConfig'];
+ $this->_cacheEnabled = true;
+ }
+ }
+/**
+ * Get the name of the backend Helper
+ * used to conditionally trigger toolbar output
+ *
+ * @return string
+ **/
+ function getName() {
+ return $this->_backEndClassName;
+ }
+/**
+ * call__
+ *
+ * Allows method calls on backend helper
+ *
+ * @param string $method
+ * @param mixed $params
+ * @access public
+ * @return void
+ */
+ function call__($method, $params) {
+ if (method_exists($this->{$this->_backEndClassName}, $method)) {
+ return $this->{$this->_backEndClassName}->dispatchMethod($method, $params);
+ }
+ }
+/**
+ * Allows for writing to panel cache from view.
+ * Some panels generate all variables in the view by
+ * necessity ie. Timer. Using this method, will allow you to replace in full
+ * the content for a panel.
+ *
+ * @param string $name Name of the panel you are replacing.
+ * @param string $content Content to write to the panel.
+ * @return boolean Sucess of write.
+ **/
+ function writeCache($name, $content) {
+ if (!$this->_cacheEnabled) {
+ return false;
+ }
+ $existing = (array)Cache::read($this->_cacheKey, $this->_cacheConfig);
+ $existing[0][$name]['content'] = $content;
+ return Cache::write($this->_cacheKey, $existing, $this->_cacheConfig);
+ }
+/**
+ * Read the toolbar
+ *
+ * @param string $name Name of the panel you want cached data for
+ * @return mixed Boolean false on failure, array of data otherwise.
+ **/
+ function readCache($name, $index = 0) {
+ if (!$this->_cacheEnabled) {
+ return false;
+ }
+ $existing = (array)Cache::read($this->_cacheKey, $this->_cacheConfig);
+ if (!isset($existing[$index][$name]['content'])) {
+ return false;
+ }
+ return $existing[$index][$name]['content'];
+ }
+/**
+ * Gets the query logs for the given connection names.
+ *
+ * ### Options
+ *
+ * - explain - Whether explain links should be generated for this connection.
+ * - cache - Whether the toolbar_state Cache should be updated.
+ * - threshold - The threshold at which a visual 'maybe slow' flag should be added.
+ * results with rows/ms lower than $threshold will be marked.
+ *
+ * @param string $connection Connection name to get logs for.
+ * @param array $options Options for the query log retrieval.
+ * @return array Array of data to be converted into a table.
+ */
+ function getQueryLogs($connection, $options = array()) {
+ $options += array('explain' => false, 'cache' => true, 'threshold' => 20);
+ App::import('Model', 'ConnectionManager');
+ $db =& ConnectionManager::getDataSource($connection);
+
+ if (!$db->isInterfaceSupported('getLog')) {
+ return array();
+ }
+
+ $out = array();
+ $log = $db->getLog();
+ foreach ($log['log'] as $i => $query) {
+ $isSlow = (
+ $query['took'] > 0 &&
+ $query['numRows'] / $query['took'] != 1 &&
+ $query['numRows'] / $query['took'] <= $options['threshold']
+ );
+ $query['actions'] = '';
+ $isHtml = ($this->getName() == 'HtmlToolbar');
+ if ($isSlow && $isHtml) {
+ $query['actions'] = sprintf(
+ '%s ',
+ __d('debug_kit', 'maybe slow', true)
+ );
+ } elseif ($isSlow) {
+ $query['actions'] = '*';
+ }
+ if ($options['explain'] && $isHtml) {
+ $query['actions'] .= $this->explainLink($query['query'], $connection);
+ }
+ if ($isHtml) {
+ $query['query'] = h($query['query']);
+ }
+ $out[] = $query;
+ }
+ if ($options['cache']) {
+ $existing = $this->readCache('sql_log');
+ $existing[$connection] = $out;
+ $this->writeCache('sql_log', $existing);
+ }
+ return $out;
+ }
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/toolbar_access/history_state.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/toolbar_access/history_state.ctp
new file mode 100644
index 000000000..21a1dcfef
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/toolbar_access/history_state.ctp
@@ -0,0 +1,29 @@
+ $panel) {
+ $panels[$panelName] = $this->element($panel['elementName'], array(
+ 'content' => $panel['content'],
+ 'plugin' => $panel['plugin']
+ ));
+}
+echo $javascript->object($panels);
+Configure::write('debug', 0);
+?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/toolbar_access/sql_explain.ctp b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/toolbar_access/sql_explain.ctp
new file mode 100644
index 000000000..a38939005
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/views/toolbar_access/sql_explain.ctp
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/css/debug_toolbar.css b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/css/debug_toolbar.css
new file mode 100644
index 000000000..46939561a
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/css/debug_toolbar.css
@@ -0,0 +1,377 @@
+/* @override http://localhost/mark_story/site/debug_kit/css/debug_toolbar.css */
+#debug-kit-toolbar {
+ position: fixed;
+ top: 0px;
+ right:0px;
+ width: 100%;
+ height: 1%;
+ overflow: visible;
+ z-index:10000;
+ font-family: helvetica, arial, sans-serif;
+ font-size: 12px;
+ direction: ltr;
+}
+#debug-kit-toolbar img {
+ border:0;
+ outline:0;
+}
+
+/* panel tabs */
+#debug-kit-toolbar #panel-tabs {
+ float: right;
+ list-style: none;
+ margin: 0;
+}
+#debug-kit-toolbar .panel-tab {
+ clear: none;
+ float: left;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+#debug-kit-toolbar .panel-tab > a {
+ float: left;
+ clear: none;
+ background: #efefef;
+ background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#cacaca));
+ background: -moz-linear-gradient(top, #efefef, #cacaca);
+ color: #222;
+ padding: 6px;
+ border-right: 1px solid #ccc;
+ border-bottom: 1px solid #aaa;
+ font-size: 12px;
+ line-height: 16px;
+ margin: 0;
+ display: block;
+ text-decoration:none;
+ text-shadow:1px 1px #eee;
+ -moz-text-shadow:1px 1px #eee;
+ -webkit-text-shadow:1px 1px #eee;
+}
+#debug-kit-toolbar .panel-tab .active {
+ background: #fff;
+ background: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#fff));
+ background: -moz-linear-gradient(top, #f5f5f5, #fff);
+}
+#debug-kit-toolbar .panel-tab > a:hover {
+ background: #fff;
+ background: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#fff));
+ background: -moz-linear-gradient(top, #f5f5f5, #fff);
+ text-decoration:underline;
+}
+#debug-kit-toolbar .panel-tab.icon a {
+ padding: 4px;
+}
+#debug-kit-toolbar .panel-tab a.edit-value {
+ float: none;
+ display: inline;
+}
+
+/* Hovering over link shows tab, useful for no js */
+#debug-kit-toolbar .panel-tab a:hover + .panel-content,
+#debug-kit-toolbar .panel-tab a + .panel-content:hover {
+ display: block;
+}
+#debug-kit-toolbar .panel-tab.icon a {
+ -webkit-border-top-left-radius: 8px 8px;
+ -webkit-border-bottom-left-radius: 8px 8px;
+ -moz-border-radius-topleft: 8px;
+ -moz-border-radius-bottomleft: 8px
+}
+#debug-kit-toolbar .panel-tab.icon img {
+ display:block;
+}
+
+/* panel content */
+#debug-kit-toolbar .panel-content {
+ position: absolute;
+ text-align: left;
+ width: auto;
+ top:28px;
+ right:0px;
+ background: #fff;
+ color: #000;
+ width:100%;
+ box-shadow:0px 5px 6px #ccc;
+ height: 200px;
+ overflow: hidden;
+}
+
+#debug-kit-toolbar .panel-resize-region {
+ padding:15px;
+ position: absolute;
+ top: 0px;
+ bottom: 14px;
+ left: 0px;
+ right: 0px;
+ overflow: auto;
+}
+
+#debug-kit-toolbar .ui-control {
+ background:#ccc;
+ background: -webkit-gradient(linear, left top, left bottom, from(#d6d6d6), to(#c2c2c2));
+ background: -moz-linear-gradient(top, #d6d6d6, #c2c2c2);
+ text-align:center;
+ border-top:1px solid #afafaf;
+ border-bottom:1px solid #7c7c7c;
+ color:#666;
+ text-shadow: 1px 1px #eee;
+ -webkit-text-shadow: 1px 1px #eee;
+ -moz-text-shadow: 1px 1px #eee;
+}
+#debug-kit-toolbar .ui-button {
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+#debug-kit-toolbar .ui-button:hover {
+ text-decoration: none;
+ background:#ccc;
+ background: -webkit-gradient(linear, left top, left bottom, from(#c2c2c2), to(#d6d6d6));
+ background: -moz-linear-gradient(top, #c2c2c2, #d6d6d6);
+}
+#debug-kit-toolbar .panel-resize-handle {
+ cursor: row-resize;
+ height:14px;
+ line-height: 14px;
+ position: absolute;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+}
+#debug-kit-toolbar .panel-maximize,
+#debug-kit-toolbar .panel-minimize {
+ float: right;
+ display: block;
+ width: 12px;
+ height: 12px;
+ line-height: 12px;
+ border-left: 1px solid #afafaf;
+ border-right: 1px solid #7c7c7c;
+}
+#debug-kit-toolbar .panel-maximize {
+ float: right;
+ margin: 10px 20px 0 0;
+ z-index: 999;
+ position: relative;
+}
+#debug-kit-toolbar .panel-minimize {
+ float: right;
+ margin: 10px 10px 0 0;
+ z-index: 999;
+ position: relative;
+}
+
+/* Hide panel content by default */
+#debug-kit-toolbar .panel-content {
+ display: none;
+}
+.panel-content p {
+ margin: 1em 0;
+}
+.panel-content h2 {
+ padding: 0;
+ margin-top:0;
+}
+.panel-content h3 {
+ padding: 0;
+ margin-top: 1em;
+}
+.panel-content .info {
+ padding: 4px;
+ border-top: 1px dashed #6c6cff;
+ border-bottom: 1px dashed #6c6cff;
+}
+#debug-kit-toolbar h1,
+#debug-kit-toolbar h2,
+#debug-kit-toolbar h3,
+#debug-kit-toolbar h4,
+#debug-kit-toolbar h5,
+#debug-kit-toolbar th {
+ color: #5d1717;
+ font-family: "Trebuchet MS", trebuchet, helvetica, arial, sans-serif;
+ margin-bottom:0.6em;
+ background:none;
+}
+#debug-kit-toolbar h1 {
+ font-size: 18px;
+}
+#debug-kit-toolbar h2 {
+ font-size: 16px;
+}
+#debug-kit-toolbar h4 {
+ font-size: 14px;
+}
+
+
+/* panel tables */
+#debug-kit-toolbar table.debug-table {
+ width: 100%;
+ border: 0;
+ clear:both;
+ margin-bottom: 20px;
+}
+#debug-kit-toolbar table.debug-table td,
+#debug-kit-toolbar table.debug-table th {
+ text-align: left;
+ border: 0;
+ padding: 3px;
+}
+#debug-kit-toolbar table.debug-table th {
+ border-bottom: 1px solid #222;
+ background: 0;
+ color: #252525;
+}
+#debug-kit-toolbar table.debug-table tr:nth-child(2n+1) td {
+ background:#f6f6f6;
+}
+#debug-kit-toolbar table.debug-table tr.even td {
+ background:#f7f7f7;
+}
+#debug-kit-toolbar .debug-timers .debug-table td:nth-child(2),
+#debug-kit-toolbar .debug-timers .debug-table th:nth-child(2) {
+ text-align:right;
+}
+
+/** code tables **/
+#debug-kit-toolbar .code-table td {
+ white-space: pre;
+ font-family: monaco, Consolas, "courier new", courier, monospaced;
+}
+#debug-kit-toolbar .code-table td:first-child {
+ width: 15%;
+}
+#debug-kit-toolbar .code-table td:last-child {
+ width: 80%;
+}
+
+#debug-kit-toolbar .panel-content.request {
+ display: block;
+}
+
+/** Neat Array styles **/
+#debug-kit-toolbar .neat-array,
+#debug-kit-toolbar .neat-array li {
+ list-style:none;
+ list-style-image:none;
+}
+.neat-array {
+ padding: 1px 2px 1px 20px;
+ background: #CE9E23;
+ list-style: none;
+ margin: 0 0 1em 0;
+}
+.neat-array .neat-array {
+ padding: 0 0 0 20px;
+ margin:0;
+ border-top:1px solid #CE9E23;
+}
+.neat-array li {
+ background: #FEF6E5;
+ border-top: 1px solid #CE9E23;
+ border-bottom: 1px solid #CE9E23;
+ margin: 0;
+ line-height: 1.5em;
+}
+.neat-array li:hover {
+ background: #fff;
+}
+.neat-array li strong {
+ padding: 0 8px;
+ font-weight: bold;
+}
+
+
+/* expandable sections */
+.neat-array li.expandable {
+ cursor: pointer;
+}
+.neat-array .expanded {
+ border-bottom:0;
+}
+.neat-array li.expandable.expanded > strong:before {
+ content: 'v ';
+}
+.neat-array li.expandable.collapsed > strong:before,
+.neat-array li.expandable.expanded .expandable.collapsed > strong:before {
+ content: '> ';
+}
+.neat-array li {
+ cursor: default;
+}
+
+#debug-kit-toolbar .debug-kit-graph-bar,
+#debug-kit-toolbar .debug-kit-graph-bar-value {
+ margin: 0;
+ padding: 0px;
+ border: none;
+ overflow: hidden;
+ height: 10px;
+}
+#debug-kit-toolbar .debug-kit-graph-bar {
+ background-color: #ddd;
+ padding:2px;
+}
+#debug-kit-toolbar .debug-kit-graph-bar-value {
+ background-color: #CE9E23;
+}
+
+/* Sql Log */
+#sql_log-tab td,
+#sql_log-tab .slow-query-container p {
+ font-family: Monaco, 'Consolas', "Courier New", Courier, monospaced;
+}
+#debug-kit-toolbar #sql_log-tab a.show-slow {
+ display:block;
+ margin: 3px;
+ float:none;
+}
+#sql_log-tab .slow-query-container p {
+ display:block;
+ clear:both;
+ margin: 20px 0 5px;
+}
+#debug-kit-toolbar #sql_log-tab .panel-content-data a {
+ background: none;
+ border:none;
+}
+#sql_log-tab .slow-query {
+ background:#e79302;
+ font-size:9px;
+ color:#fff;
+ padding: 2px;
+ white-space:nowrap;
+}
+#sql_log-tab input[type=submit] {
+ border: 0;
+ background: transparent;
+ cursor: pointer;
+ font-size: 12px;
+ font-family: Monaco, 'Consolas', "Courier New", Courier, monospaced;
+}
+#sql_log-tab input[type=submit]:hover {
+ color: darkred;
+}
+
+/* previous panels */
+#debug-kit-toolbar .panel-history {
+ display: none;
+ background:#eeffff;
+}
+#debug-kit-toolbar #history-tab ul {
+ margin: 20px 0 0 20px;
+}
+#debug-kit-toolbar #history-tab li {
+ margin: 0 0 5px 0;
+}
+#debug-kit-toolbar #history-tab .panel-content-data a {
+ float: none;
+ display:block;
+}
+#debug-kit-toolbar #history-tab a.active {
+ background: #FEF6E5;
+}
+#debug-kit-toolbar #history-tab a.loading:after {
+ content : ' Loading...';
+ font-style:italic;
+}
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/img/cake.icon.png b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/img/cake.icon.png
new file mode 100644
index 000000000..394fa42d5
Binary files /dev/null and b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/img/cake.icon.png differ
diff --git a/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/js/js_debug_toolbar.js b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/js/js_debug_toolbar.js
new file mode 100644
index 000000000..57cc1cc08
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/plugins/debug_kit/webroot/js/js_debug_toolbar.js
@@ -0,0 +1,767 @@
+/**
+ * Debug Toolbar Javascript.
+ *
+ * Creates the DEBUGKIT namespace and provides methods for extending
+ * and enhancing the Html toolbar. Includes library agnostic Event, Element,
+ * Cookie and Request wrappers.
+ *
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org
+ * @package debug_kit
+ * @subpackage debug_kit.views.helpers
+ * @since DebugKit 0.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+var DEBUGKIT = function () {
+ var undef;
+ return {
+ module: function (newmodule) {
+ if (this[newmodule] === undef) {
+ this[newmodule] = {};
+ return this[newmodule];
+ }
+ return this[newmodule];
+ }
+ };
+}() ;
+
+DEBUGKIT.loader = function () {
+ return {
+ //list of methods to run on startup.
+ _startup: [],
+
+ //register a new method to be run on dom ready.
+ register: function (method) {
+ this._startup.push(method);
+ },
+
+ init: function () {
+ for (var i = 0, callback; callback = this._startup[i]; i++) {
+ callback.init();
+ }
+ }
+ };
+}();
+
+//Util module and Element utility class.
+DEBUGKIT.module('Util');
+DEBUGKIT.Util.Element = {
+
+ //test if an element is a name node.
+ nodeName: function (element, name) {
+ return element.nodeName && element.nodeName.toLowerCase() == name.toLowerCase();
+ },
+
+ //return a boolean if the element has the classname
+ hasClass: function (element, className) {
+ if (!element.className) {
+ return false;
+ }
+ return element.className.indexOf(className) > -1;
+ },
+
+ addClass: function (element, className) {
+ if (!element.className) {
+ element.className = className;
+ return;
+ }
+ element.className = element.className.replace(/^(.*)$/, '$1 ' + className);
+ },
+
+ removeClass: function (element, className) {
+ if (DEBUGKIT.Util.isArray(element)) {
+ DEBUGKIT.Util.Collection.apply(element, function (element) {
+ DEBUGKIT.Util.Element.removeClass(element, className);
+ });
+ }
+ if (!element.className) {
+ return false;
+ }
+ element.className = element.className.replace(new RegExp(' ?(' + className +') ?'), '');
+ },
+
+ swapClass: function (element, removeClass, addClass) {
+ if (!element.className) {
+ return false;
+ }
+ element.className = element.className.replace(removeClass, addClass);
+ },
+
+ show: function (element) {
+ element.style.display = 'block';
+ },
+
+ hide: function (element) {
+ element.style.display = 'none';
+ },
+
+ //go between hide() and show() depending on element.style.display
+ toggle: function (element) {
+ if (element.style.display == 'none') {
+ this.show(element);
+ return;
+ }
+ this.hide(element);
+ },
+
+ _walk: function (element, walk) {
+ var sibling = element[walk];
+ while (true) {
+ if (sibling.nodeType == 1) {
+ break;
+ }
+ sibling = sibling[walk];
+ }
+ return sibling;
+ },
+
+ getNext: function (element) {
+ return this._walk(element, 'nextSibling');
+ },
+
+ getPrevious: function (element) {
+ return this._walk(element, 'previousSibling');
+ },
+
+ //get or set an element's height, omit value to get, add value (integer) to set.
+ height: function (element, value) {
+ //get value
+ if (value === undefined) {
+ return parseInt(this.getStyle(element, 'height'));
+ }
+ element.style.height = value + 'px';
+ },
+
+ //gets the style in css format for property
+ getStyle: function (element, property) {
+ if (element.currentStyle) {
+ property = property.replace(/-[a-z]/g, function (match) {
+ return match.charAt(1).toUpperCase();
+ });
+ return element.currentStyle[property];
+ }
+ if (window.getComputedStyle) {
+ return document.defaultView.getComputedStyle(element, null).getPropertyValue(property);
+ }
+ }
+};
+
+DEBUGKIT.Util.Collection = {
+ /*
+ Apply the passed function to each item in the collection.
+ The current element in the collection will be `this` in the callback
+ The callback is also passed the element and the index as arguments.
+ Optionally you can supply a binding parameter to change `this` in the callback.
+ */
+ apply: function (collection, callback, binding) {
+ var name, thisVar, i = 0, len = collection.length;
+
+ if (len === undefined) {
+ for (name in collection) {
+ thisVar = (binding === undefined) ? collection[name] : binding;
+ callback.apply(thisVar, [collection[name], name]);
+ }
+ } else {
+ for (; i < len; i++) {
+ thisVar = (binding === undefined) ? collection[i] : binding;
+ callback.apply(thisVar, [collection[i], i]);
+ }
+ }
+ }
+}
+
+
+//Event binding
+DEBUGKIT.Util.Event = function () {
+ var _listeners = {},
+ _eventId = 0;
+
+ var preventDefault = function () {
+ this.returnValue = false;
+ }
+
+ var stopPropagation = function () {
+ this.cancelBubble = true;
+ }
+
+ // Fixes IE's broken event object, adds in common methods + properties.
+ var fixEvent = function (event) {
+ if (!event.preventDefault) {
+ event.preventDefault = preventDefault;
+ }
+ if (!event.stopPropagation) {
+ event.stopPropagation = stopPropagation;
+ }
+ if (!event.target) {
+ event.target = event.srcElement || document;
+ }
+ if (event.pageX == null && event.clientX != null) {
+ var doc = document.body;
+ event.pageX = event.clientX + (doc.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc.scrollTop || 0) - (doc.clientTop || 0);
+ }
+ return event;
+ }
+
+ return {
+ // bind an event listener of type to element, handler is your method.
+ addEvent: function(element, type, handler, capture) {
+ capture = (capture === undefined) ? false : capture;
+
+ var callback = function (event) {
+ event = fixEvent(event || window.event);
+ handler.apply(element, [event]);
+ };
+
+ if (element.addEventListener) {
+ element.addEventListener(type, callback, capture);
+ } else if (element.attachEvent) {
+ type = 'on' + type;
+ element.attachEvent(type, callback);
+ } else {
+ type = 'on' + type;
+ element[type] = callback;
+ }
+ _listeners[++_eventId] = {element: element, type: type, handler: callback};
+ },
+
+ // destroy an event listener. requires the exact same function as was used for attaching
+ // the event.
+ removeEvent: function (element, type, handler) {
+ if (element.removeEventListener) {
+ element.removeEventListener(type, handler, false);
+ } else if (element.detachEvent) {
+ type = 'on' + type;
+ element.detachEvent(type, handler);
+ } else {
+ type = 'on' + type;
+ element[type] = null;
+ }
+ },
+
+ // bind an event to the DOMContentLoaded or other similar event.
+ domready: function(callback) {
+ if (document.addEventListener) {
+ return document.addEventListener("DOMContentLoaded", callback, false);
+ }
+
+ if (document.all && !window.opera) {
+ //Define a "blank" external JavaScript tag
+ document.write('', 'js');
+ $this->mapHandler('comment', 'ignore');
+ $this->addEntryPattern('', 'comment');
+ }
+
+ /**
+ * Pattern matches to start and end a tag.
+ * @param string $tag Name of tag to scan for.
+ * @access private
+ */
+ protected function addTag($tag) {
+ $this->addSpecialPattern("$tag>", 'text', 'acceptEndToken');
+ $this->addEntryPattern("<$tag", 'text', 'tag');
+ }
+
+ /**
+ * Pattern matches to parse the inside of a tag
+ * including the attributes and their quoting.
+ * @access private
+ */
+ protected function addInTagTokens() {
+ $this->mapHandler('tag', 'acceptStartToken');
+ $this->addSpecialPattern('\s+', 'tag', 'ignore');
+ $this->addAttributeTokens();
+ $this->addExitPattern('/>', 'tag');
+ $this->addExitPattern('>', 'tag');
+ }
+
+ /**
+ * Matches attributes that are either single quoted,
+ * double quoted or unquoted.
+ * @access private
+ */
+ protected function addAttributeTokens() {
+ $this->mapHandler('dq_attribute', 'acceptAttributeToken');
+ $this->addEntryPattern('=\s*"', 'tag', 'dq_attribute');
+ $this->addPattern("\\\\\"", 'dq_attribute');
+ $this->addExitPattern('"', 'dq_attribute');
+ $this->mapHandler('sq_attribute', 'acceptAttributeToken');
+ $this->addEntryPattern("=\s*'", 'tag', 'sq_attribute');
+ $this->addPattern("\\\\'", 'sq_attribute');
+ $this->addExitPattern("'", 'sq_attribute');
+ $this->mapHandler('uq_attribute', 'acceptAttributeToken');
+ $this->addSpecialPattern('=\s*[^>\s]*', 'tag', 'uq_attribute');
+ }
+}
+
+/**
+ * Converts HTML tokens into selected SAX events.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleHtmlSaxParser {
+ private $lexer;
+ private $listener;
+ private $tag;
+ private $attributes;
+ private $current_attribute;
+
+ /**
+ * Sets the listener.
+ * @param SimplePhpPageBuilder $listener SAX event handler.
+ * @access public
+ */
+ function __construct($listener) {
+ $this->listener = $listener;
+ $this->lexer = $this->createLexer($this);
+ $this->tag = '';
+ $this->attributes = array();
+ $this->current_attribute = '';
+ }
+
+ /**
+ * Runs the content through the lexer which
+ * should call back to the acceptors.
+ * @param string $raw Page text to parse.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function parse($raw) {
+ return $this->lexer->parse($raw);
+ }
+
+ /**
+ * Sets up the matching lexer. Starts in 'text' mode.
+ * @param SimpleSaxParser $parser Event generator, usually $self.
+ * @return SimpleLexer Lexer suitable for this parser.
+ * @access public
+ */
+ static function createLexer(&$parser) {
+ return new SimpleHtmlLexer($parser);
+ }
+
+ /**
+ * Accepts a token from the tag mode. If the
+ * starting element completes then the element
+ * is dispatched and the current attributes
+ * set back to empty. The element or attribute
+ * name is converted to lower case.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptStartToken($token, $event) {
+ if ($event == LEXER_ENTER) {
+ $this->tag = strtolower(substr($token, 1));
+ return true;
+ }
+ if ($event == LEXER_EXIT) {
+ $success = $this->listener->startElement(
+ $this->tag,
+ $this->attributes);
+ $this->tag = '';
+ $this->attributes = array();
+ return $success;
+ }
+ if ($token != '=') {
+ $this->current_attribute = strtolower(html_entity_decode($token, ENT_QUOTES));
+ $this->attributes[$this->current_attribute] = '';
+ }
+ return true;
+ }
+
+ /**
+ * Accepts a token from the end tag mode.
+ * The element name is converted to lower case.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptEndToken($token, $event) {
+ if (! preg_match('/<\/(.*)>/', $token, $matches)) {
+ return false;
+ }
+ return $this->listener->endElement(strtolower($matches[1]));
+ }
+
+ /**
+ * Part of the tag data.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptAttributeToken($token, $event) {
+ if ($this->current_attribute) {
+ if ($event == LEXER_UNMATCHED) {
+ $this->attributes[$this->current_attribute] .=
+ html_entity_decode($token, ENT_QUOTES);
+ }
+ if ($event == LEXER_SPECIAL) {
+ $this->attributes[$this->current_attribute] .=
+ preg_replace('/^=\s*/' , '', html_entity_decode($token, ENT_QUOTES));
+ }
+ }
+ return true;
+ }
+
+ /**
+ * A character entity.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptEntityToken($token, $event) {
+ }
+
+ /**
+ * Character data between tags regarded as
+ * important.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptTextToken($token, $event) {
+ return $this->listener->addContent($token);
+ }
+
+ /**
+ * Incoming data to be ignored.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function ignore($token, $event) {
+ return true;
+ }
+}
+
+/**
+ * SAX event handler. Maintains a list of
+ * open tags and dispatches them as they close.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimplePhpPageBuilder {
+ private $tags;
+ private $page;
+ private $private_content_tag;
+ private $open_forms = array();
+ private $complete_forms = array();
+ private $frameset = false;
+ private $loading_frames = array();
+ private $frameset_nesting_level = 0;
+ private $left_over_labels = array();
+
+ /**
+ * Frees up any references so as to allow the PHP garbage
+ * collection from unset() to work.
+ * @access public
+ */
+ function free() {
+ unset($this->tags);
+ unset($this->page);
+ unset($this->private_content_tags);
+ $this->open_forms = array();
+ $this->complete_forms = array();
+ $this->frameset = false;
+ $this->loading_frames = array();
+ $this->frameset_nesting_level = 0;
+ $this->left_over_labels = array();
+ }
+
+ /**
+ * This builder is always available.
+ * @return boolean Always true.
+ */
+ function can() {
+ return true;
+ }
+
+ /**
+ * Reads the raw content and send events
+ * into the page to be built.
+ * @param $response SimpleHttpResponse Fetched response.
+ * @return SimplePage Newly parsed page.
+ * @access public
+ */
+ function parse($response) {
+ $this->tags = array();
+ $this->page = $this->createPage($response);
+ $parser = $this->createParser($this);
+ $parser->parse($response->getContent());
+ $this->acceptPageEnd();
+ $page = $this->page;
+ $this->free();
+ return $page;
+ }
+
+ /**
+ * Creates an empty page.
+ * @return SimplePage New unparsed page.
+ * @access protected
+ */
+ protected function createPage($response) {
+ return new SimplePage($response);
+ }
+
+ /**
+ * Creates the parser used with the builder.
+ * @param SimplePhpPageBuilder $listener Target of parser.
+ * @return SimpleSaxParser Parser to generate
+ * events for the builder.
+ * @access protected
+ */
+ protected function createParser(&$listener) {
+ return new SimpleHtmlSaxParser($listener);
+ }
+
+ /**
+ * Start of element event. Opens a new tag.
+ * @param string $name Element name.
+ * @param hash $attributes Attributes without content
+ * are marked as true.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function startElement($name, $attributes) {
+ $factory = new SimpleTagBuilder();
+ $tag = $factory->createTag($name, $attributes);
+ if (! $tag) {
+ return true;
+ }
+ if ($tag->getTagName() == 'label') {
+ $this->acceptLabelStart($tag);
+ $this->openTag($tag);
+ return true;
+ }
+ if ($tag->getTagName() == 'form') {
+ $this->acceptFormStart($tag);
+ return true;
+ }
+ if ($tag->getTagName() == 'frameset') {
+ $this->acceptFramesetStart($tag);
+ return true;
+ }
+ if ($tag->getTagName() == 'frame') {
+ $this->acceptFrame($tag);
+ return true;
+ }
+ if ($tag->isPrivateContent() && ! isset($this->private_content_tag)) {
+ $this->private_content_tag = &$tag;
+ }
+ if ($tag->expectEndTag()) {
+ $this->openTag($tag);
+ return true;
+ }
+ $this->acceptTag($tag);
+ return true;
+ }
+
+ /**
+ * End of element event.
+ * @param string $name Element name.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function endElement($name) {
+ if ($name == 'label') {
+ $this->acceptLabelEnd();
+ return true;
+ }
+ if ($name == 'form') {
+ $this->acceptFormEnd();
+ return true;
+ }
+ if ($name == 'frameset') {
+ $this->acceptFramesetEnd();
+ return true;
+ }
+ if ($this->hasNamedTagOnOpenTagStack($name)) {
+ $tag = array_pop($this->tags[$name]);
+ if ($tag->isPrivateContent() && $this->private_content_tag->getTagName() == $name) {
+ unset($this->private_content_tag);
+ }
+ $this->addContentTagToOpenTags($tag);
+ $this->acceptTag($tag);
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Test to see if there are any open tags awaiting
+ * closure that match the tag name.
+ * @param string $name Element name.
+ * @return boolean True if any are still open.
+ * @access private
+ */
+ protected function hasNamedTagOnOpenTagStack($name) {
+ return isset($this->tags[$name]) && (count($this->tags[$name]) > 0);
+ }
+
+ /**
+ * Unparsed, but relevant data. The data is added
+ * to every open tag.
+ * @param string $text May include unparsed tags.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function addContent($text) {
+ if (isset($this->private_content_tag)) {
+ $this->private_content_tag->addContent($text);
+ } else {
+ $this->addContentToAllOpenTags($text);
+ }
+ return true;
+ }
+
+ /**
+ * Any content fills all currently open tags unless it
+ * is part of an option tag.
+ * @param string $text May include unparsed tags.
+ * @access private
+ */
+ protected function addContentToAllOpenTags($text) {
+ foreach (array_keys($this->tags) as $name) {
+ for ($i = 0, $count = count($this->tags[$name]); $i < $count; $i++) {
+ $this->tags[$name][$i]->addContent($text);
+ }
+ }
+ }
+
+ /**
+ * Parsed data in tag form. The parsed tag is added
+ * to every open tag. Used for adding options to select
+ * fields only.
+ * @param SimpleTag $tag Option tags only.
+ * @access private
+ */
+ protected function addContentTagToOpenTags(&$tag) {
+ if ($tag->getTagName() != 'option') {
+ return;
+ }
+ foreach (array_keys($this->tags) as $name) {
+ for ($i = 0, $count = count($this->tags[$name]); $i < $count; $i++) {
+ $this->tags[$name][$i]->addTag($tag);
+ }
+ }
+ }
+
+ /**
+ * Opens a tag for receiving content. Multiple tags
+ * will be receiving input at the same time.
+ * @param SimpleTag $tag New content tag.
+ * @access private
+ */
+ protected function openTag($tag) {
+ $name = $tag->getTagName();
+ if (! in_array($name, array_keys($this->tags))) {
+ $this->tags[$name] = array();
+ }
+ $this->tags[$name][] = $tag;
+ }
+
+ /**
+ * Adds a tag to the page.
+ * @param SimpleTag $tag Tag to accept.
+ * @access public
+ */
+ protected function acceptTag($tag) {
+ if ($tag->getTagName() == "a") {
+ $this->page->addLink($tag);
+ } elseif ($tag->getTagName() == "base") {
+ $this->page->setBase($tag->getAttribute('href'));
+ } elseif ($tag->getTagName() == "title") {
+ $this->page->setTitle($tag);
+ } elseif ($this->isFormElement($tag->getTagName())) {
+ for ($i = 0; $i < count($this->open_forms); $i++) {
+ $this->open_forms[$i]->addWidget($tag);
+ }
+ $this->last_widget = $tag;
+ }
+ }
+
+ /**
+ * Opens a label for a described widget.
+ * @param SimpleFormTag $tag Tag to accept.
+ * @access public
+ */
+ protected function acceptLabelStart($tag) {
+ $this->label = $tag;
+ unset($this->last_widget);
+ }
+
+ /**
+ * Closes the most recently opened label.
+ * @access public
+ */
+ protected function acceptLabelEnd() {
+ if (isset($this->label)) {
+ if (isset($this->last_widget)) {
+ $this->last_widget->setLabel($this->label->getText());
+ unset($this->last_widget);
+ } else {
+ $this->left_over_labels[] = SimpleTestCompatibility::copy($this->label);
+ }
+ unset($this->label);
+ }
+ }
+
+ /**
+ * Tests to see if a tag is a possible form
+ * element.
+ * @param string $name HTML element name.
+ * @return boolean True if form element.
+ * @access private
+ */
+ protected function isFormElement($name) {
+ return in_array($name, array('input', 'button', 'textarea', 'select'));
+ }
+
+ /**
+ * Opens a form. New widgets go here.
+ * @param SimpleFormTag $tag Tag to accept.
+ * @access public
+ */
+ protected function acceptFormStart($tag) {
+ $this->open_forms[] = new SimpleForm($tag, $this->page);
+ }
+
+ /**
+ * Closes the most recently opened form.
+ * @access public
+ */
+ protected function acceptFormEnd() {
+ if (count($this->open_forms)) {
+ $this->complete_forms[] = array_pop($this->open_forms);
+ }
+ }
+
+ /**
+ * Opens a frameset. A frameset may contain nested
+ * frameset tags.
+ * @param SimpleFramesetTag $tag Tag to accept.
+ * @access public
+ */
+ protected function acceptFramesetStart($tag) {
+ if (! $this->isLoadingFrames()) {
+ $this->frameset = $tag;
+ }
+ $this->frameset_nesting_level++;
+ }
+
+ /**
+ * Closes the most recently opened frameset.
+ * @access public
+ */
+ protected function acceptFramesetEnd() {
+ if ($this->isLoadingFrames()) {
+ $this->frameset_nesting_level--;
+ }
+ }
+
+ /**
+ * Takes a single frame tag and stashes it in
+ * the current frame set.
+ * @param SimpleFrameTag $tag Tag to accept.
+ * @access public
+ */
+ protected function acceptFrame($tag) {
+ if ($this->isLoadingFrames()) {
+ if ($tag->getAttribute('src')) {
+ $this->loading_frames[] = $tag;
+ }
+ }
+ }
+
+ /**
+ * Test to see if in the middle of reading
+ * a frameset.
+ * @return boolean True if inframeset.
+ * @access private
+ */
+ protected function isLoadingFrames() {
+ return $this->frameset and $this->frameset_nesting_level > 0;
+ }
+
+ /**
+ * Marker for end of complete page. Any work in
+ * progress can now be closed.
+ * @access public
+ */
+ protected function acceptPageEnd() {
+ while (count($this->open_forms)) {
+ $this->complete_forms[] = array_pop($this->open_forms);
+ }
+ foreach ($this->left_over_labels as $label) {
+ for ($i = 0, $count = count($this->complete_forms); $i < $count; $i++) {
+ $this->complete_forms[$i]->attachLabelBySelector(
+ new SimpleById($label->getFor()),
+ $label->getText());
+ }
+ }
+ $this->page->setForms($this->complete_forms);
+ $this->page->setFrames($this->loading_frames);
+ }
+}
+?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/vendors/simpletest/reflection_php4.php b/code/ryzom/tools/server/www/webtt/vendors/simpletest/reflection_php4.php
new file mode 100644
index 000000000..39801ea1b
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/vendors/simpletest/reflection_php4.php
@@ -0,0 +1,136 @@
+_interface = $interface;
+ }
+
+ /**
+ * Checks that a class has been declared.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExists() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExistsSansAutoload() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Checks that a class or interface has been
+ * declared.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExists() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExistsSansAutoload() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Gets the list of methods on a class or
+ * interface.
+ * @returns array List of method names.
+ * @access public
+ */
+ function getMethods() {
+ return get_class_methods($this->_interface);
+ }
+
+ /**
+ * Gets the list of interfaces from a class. If the
+ * class name is actually an interface then just that
+ * interface is returned.
+ * @returns array List of interfaces.
+ * @access public
+ */
+ function getInterfaces() {
+ return array();
+ }
+
+ /**
+ * Finds the parent class name.
+ * @returns string Parent class name.
+ * @access public
+ */
+ function getParent() {
+ return strtolower(get_parent_class($this->_interface));
+ }
+
+ /**
+ * Determines if the class is abstract, which for PHP 4
+ * will never be the case.
+ * @returns boolean True if abstract.
+ * @access public
+ */
+ function isAbstract() {
+ return false;
+ }
+
+ /**
+ * Determines if the the entity is an interface, which for PHP 4
+ * will never be the case.
+ * @returns boolean True if interface.
+ * @access public
+ */
+ function isInterface() {
+ return false;
+ }
+
+ /**
+ * Scans for final methods, but as it's PHP 4 there
+ * aren't any.
+ * @returns boolean True if the class has a final method.
+ * @access public
+ */
+ function hasFinal() {
+ return false;
+ }
+
+ /**
+ * Gets the source code matching the declaration
+ * of a method.
+ * @param string $method Method name.
+ * @access public
+ */
+ function getSignature($method) {
+ return "function &$method()";
+ }
+}
+?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/vendors/simpletest/reflection_php5.php b/code/ryzom/tools/server/www/webtt/vendors/simpletest/reflection_php5.php
new file mode 100644
index 000000000..43d8a7b28
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/vendors/simpletest/reflection_php5.php
@@ -0,0 +1,386 @@
+interface = $interface;
+ }
+
+ /**
+ * Checks that a class has been declared. Versions
+ * before PHP5.0.2 need a check that it's not really
+ * an interface.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExists() {
+ if (! class_exists($this->interface)) {
+ return false;
+ }
+ $reflection = new ReflectionClass($this->interface);
+ return ! $reflection->isInterface();
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExistsSansAutoload() {
+ return class_exists($this->interface, false);
+ }
+
+ /**
+ * Checks that a class or interface has been
+ * declared.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExists() {
+ return $this->classOrInterfaceExistsWithAutoload($this->interface, true);
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExistsSansAutoload() {
+ return $this->classOrInterfaceExistsWithAutoload($this->interface, false);
+ }
+
+ /**
+ * Needed to select the autoload feature in PHP5
+ * for classes created dynamically.
+ * @param string $interface Class or interface name.
+ * @param boolean $autoload True totriggerautoload.
+ * @return boolean True if interface defined.
+ * @access private
+ */
+ protected function classOrInterfaceExistsWithAutoload($interface, $autoload) {
+ if (function_exists('interface_exists')) {
+ if (interface_exists($this->interface, $autoload)) {
+ return true;
+ }
+ }
+ return class_exists($this->interface, $autoload);
+ }
+
+ /**
+ * Gets the list of methods on a class or
+ * interface.
+ * @returns array List of method names.
+ * @access public
+ */
+ function getMethods() {
+ return array_unique(get_class_methods($this->interface));
+ }
+
+ /**
+ * Gets the list of interfaces from a class. If the
+ * class name is actually an interface then just that
+ * interface is returned.
+ * @returns array List of interfaces.
+ * @access public
+ */
+ function getInterfaces() {
+ $reflection = new ReflectionClass($this->interface);
+ if ($reflection->isInterface()) {
+ return array($this->interface);
+ }
+ return $this->onlyParents($reflection->getInterfaces());
+ }
+
+ /**
+ * Gets the list of methods for the implemented
+ * interfaces only.
+ * @returns array List of enforced method signatures.
+ * @access public
+ */
+ function getInterfaceMethods() {
+ $methods = array();
+ foreach ($this->getInterfaces() as $interface) {
+ $methods = array_merge($methods, get_class_methods($interface));
+ }
+ return array_unique($methods);
+ }
+
+ /**
+ * Checks to see if the method signature has to be tightly
+ * specified.
+ * @param string $method Method name.
+ * @returns boolean True if enforced.
+ * @access private
+ */
+ protected function isInterfaceMethod($method) {
+ return in_array($method, $this->getInterfaceMethods());
+ }
+
+ /**
+ * Finds the parent class name.
+ * @returns string Parent class name.
+ * @access public
+ */
+ function getParent() {
+ $reflection = new ReflectionClass($this->interface);
+ $parent = $reflection->getParentClass();
+ if ($parent) {
+ return $parent->getName();
+ }
+ return false;
+ }
+
+ /**
+ * Trivially determines if the class is abstract.
+ * @returns boolean True if abstract.
+ * @access public
+ */
+ function isAbstract() {
+ $reflection = new ReflectionClass($this->interface);
+ return $reflection->isAbstract();
+ }
+
+ /**
+ * Trivially determines if the class is an interface.
+ * @returns boolean True if interface.
+ * @access public
+ */
+ function isInterface() {
+ $reflection = new ReflectionClass($this->interface);
+ return $reflection->isInterface();
+ }
+
+ /**
+ * Scans for final methods, as they screw up inherited
+ * mocks by not allowing you to override them.
+ * @returns boolean True if the class has a final method.
+ * @access public
+ */
+ function hasFinal() {
+ $reflection = new ReflectionClass($this->interface);
+ foreach ($reflection->getMethods() as $method) {
+ if ($method->isFinal()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Whittles a list of interfaces down to only the
+ * necessary top level parents.
+ * @param array $interfaces Reflection API interfaces
+ * to reduce.
+ * @returns array List of parent interface names.
+ * @access private
+ */
+ protected function onlyParents($interfaces) {
+ $parents = array();
+ $blacklist = array();
+ foreach ($interfaces as $interface) {
+ foreach($interfaces as $possible_parent) {
+ if ($interface->getName() == $possible_parent->getName()) {
+ continue;
+ }
+ if ($interface->isSubClassOf($possible_parent)) {
+ $blacklist[$possible_parent->getName()] = true;
+ }
+ }
+ if (!isset($blacklist[$interface->getName()])) {
+ $parents[] = $interface->getName();
+ }
+ }
+ return $parents;
+ }
+
+ /**
+ * Checks whether a method is abstract or not.
+ * @param string $name Method name.
+ * @return bool true if method is abstract, else false
+ * @access private
+ */
+ protected function isAbstractMethod($name) {
+ $interface = new ReflectionClass($this->interface);
+ if (! $interface->hasMethod($name)) {
+ return false;
+ }
+ return $interface->getMethod($name)->isAbstract();
+ }
+
+ /**
+ * Checks whether a method is the constructor.
+ * @param string $name Method name.
+ * @return bool true if method is the constructor
+ * @access private
+ */
+ protected function isConstructor($name) {
+ return ($name == '__construct') || ($name == $this->interface);
+ }
+
+ /**
+ * Checks whether a method is abstract in all parents or not.
+ * @param string $name Method name.
+ * @return bool true if method is abstract in parent, else false
+ * @access private
+ */
+ protected function isAbstractMethodInParents($name) {
+ $interface = new ReflectionClass($this->interface);
+ $parent = $interface->getParentClass();
+ while($parent) {
+ if (! $parent->hasMethod($name)) {
+ return false;
+ }
+ if ($parent->getMethod($name)->isAbstract()) {
+ return true;
+ }
+ $parent = $parent->getParentClass();
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether a method is static or not.
+ * @param string $name Method name
+ * @return bool true if method is static, else false
+ * @access private
+ */
+ protected function isStaticMethod($name) {
+ $interface = new ReflectionClass($this->interface);
+ if (! $interface->hasMethod($name)) {
+ return false;
+ }
+ return $interface->getMethod($name)->isStatic();
+ }
+
+ /**
+ * Writes the source code matching the declaration
+ * of a method.
+ * @param string $name Method name.
+ * @return string Method signature up to last
+ * bracket.
+ * @access public
+ */
+ function getSignature($name) {
+ if ($name == '__set') {
+ return 'function __set($key, $value)';
+ }
+ if ($name == '__call') {
+ return 'function __call($method, $arguments)';
+ }
+ if (version_compare(phpversion(), '5.1.0', '>=')) {
+ if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
+ return "function {$name}(\$key)";
+ }
+ }
+ if ($name == '__toString') {
+ return "function $name()";
+ }
+
+ // This wonky try-catch is a work around for a faulty method_exists()
+ // in early versions of PHP 5 which would return false for static
+ // methods. The Reflection classes work fine, but hasMethod()
+ // doesn't exist prior to PHP 5.1.0, so we need to use a more crude
+ // detection method.
+ try {
+ $interface = new ReflectionClass($this->interface);
+ $interface->getMethod($name);
+ } catch (ReflectionException $e) {
+ return "function $name()";
+ }
+ return $this->getFullSignature($name);
+ }
+
+ /**
+ * For a signature specified in an interface, full
+ * details must be replicated to be a valid implementation.
+ * @param string $name Method name.
+ * @return string Method signature up to last
+ * bracket.
+ * @access private
+ */
+ protected function getFullSignature($name) {
+ $interface = new ReflectionClass($this->interface);
+ $method = $interface->getMethod($name);
+ $reference = $method->returnsReference() ? '&' : '';
+ $static = $method->isStatic() ? 'static ' : '';
+ return "{$static}function $reference$name(" .
+ implode(', ', $this->getParameterSignatures($method)) .
+ ")";
+ }
+
+ /**
+ * Gets the source code for each parameter.
+ * @param ReflectionMethod $method Method object from
+ * reflection API
+ * @return array List of strings, each
+ * a snippet of code.
+ * @access private
+ */
+ protected function getParameterSignatures($method) {
+ $signatures = array();
+ foreach ($method->getParameters() as $parameter) {
+ $signature = '';
+ $type = $parameter->getClass();
+ if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {
+ $signature .= 'array ';
+ } elseif (!is_null($type)) {
+ $signature .= $type->getName() . ' ';
+ }
+ if ($parameter->isPassedByReference()) {
+ $signature .= '&';
+ }
+ $signature .= '$' . $this->suppressSpurious($parameter->getName());
+ if ($this->isOptional($parameter)) {
+ $signature .= ' = null';
+ }
+ $signatures[] = $signature;
+ }
+ return $signatures;
+ }
+
+ /**
+ * The SPL library has problems with the
+ * Reflection library. In particular, you can
+ * get extra characters in parameter names :(.
+ * @param string $name Parameter name.
+ * @return string Cleaner name.
+ * @access private
+ */
+ protected function suppressSpurious($name) {
+ return str_replace(array('[', ']', ' '), '', $name);
+ }
+
+ /**
+ * Test of a reflection parameter being optional
+ * that works with early versions of PHP5.
+ * @param reflectionParameter $parameter Is this optional.
+ * @return boolean True if optional.
+ * @access private
+ */
+ protected function isOptional($parameter) {
+ if (method_exists($parameter, 'isOptional')) {
+ return $parameter->isOptional();
+ }
+ return false;
+ }
+}
+?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/vendors/simpletest/remote.php b/code/ryzom/tools/server/www/webtt/vendors/simpletest/remote.php
new file mode 100644
index 000000000..4bb37b7c5
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/vendors/simpletest/remote.php
@@ -0,0 +1,115 @@
+url = $url;
+ $this->dry_url = $dry_url ? $dry_url : $url;
+ $this->size = false;
+ }
+
+ /**
+ * Accessor for the test name for subclasses.
+ * @return string Name of the test.
+ * @access public
+ */
+ function getLabel() {
+ return $this->url;
+ }
+
+ /**
+ * Runs the top level test for this class. Currently
+ * reads the data as a single chunk. I'll fix this
+ * once I have added iteration to the browser.
+ * @param SimpleReporter $reporter Target of test results.
+ * @returns boolean True if no failures.
+ * @access public
+ */
+ function run($reporter) {
+ $browser = $this->createBrowser();
+ $xml = $browser->get($this->url);
+ if (! $xml) {
+ trigger_error('Cannot read remote test URL [' . $this->url . ']');
+ return false;
+ }
+ $parser = $this->createParser($reporter);
+ if (! $parser->parse($xml)) {
+ trigger_error('Cannot parse incoming XML from [' . $this->url . ']');
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Creates a new web browser object for fetching
+ * the XML report.
+ * @return SimpleBrowser New browser.
+ * @access protected
+ */
+ protected function createBrowser() {
+ return new SimpleBrowser();
+ }
+
+ /**
+ * Creates the XML parser.
+ * @param SimpleReporter $reporter Target of test results.
+ * @return SimpleTestXmlListener XML reader.
+ * @access protected
+ */
+ protected function createParser($reporter) {
+ return new SimpleTestXmlParser($reporter);
+ }
+
+ /**
+ * Accessor for the number of subtests.
+ * @return integer Number of test cases.
+ * @access public
+ */
+ function getSize() {
+ if ($this->size === false) {
+ $browser = $this->createBrowser();
+ $xml = $browser->get($this->dry_url);
+ if (! $xml) {
+ trigger_error('Cannot read remote test URL [' . $this->dry_url . ']');
+ return false;
+ }
+ $reporter = new SimpleReporter();
+ $parser = $this->createParser($reporter);
+ if (! $parser->parse($xml)) {
+ trigger_error('Cannot parse incoming XML from [' . $this->dry_url . ']');
+ return false;
+ }
+ $this->size = $reporter->getTestCaseCount();
+ }
+ return $this->size;
+ }
+}
+?>
\ No newline at end of file
diff --git a/code/ryzom/tools/server/www/webtt/vendors/simpletest/reporter.php b/code/ryzom/tools/server/www/webtt/vendors/simpletest/reporter.php
new file mode 100644
index 000000000..bf8d2ac11
--- /dev/null
+++ b/code/ryzom/tools/server/www/webtt/vendors/simpletest/reporter.php
@@ -0,0 +1,445 @@
+character_set = $character_set;
+ }
+
+ /**
+ * Paints the top of the web page setting the
+ * title to the name of the starting test.
+ * @param string $test_name Name class of test.
+ * @access public
+ */
+ function paintHeader($test_name) {
+ $this->sendNoCacheHeaders();
+ print "";
+ print "\n