summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--[-rwxr-xr-x]demos/blog-tutorial/protected/pages/Day2/CreateAR.page123
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/blog_wsat_generate_ar.pngbin0 -> 69184 bytes
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/wsat_login.pngbin0 -> 47951 bytes
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/controls/TopicList.tpl7
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/controls/es/TopicList.tpl7
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/controls/fr/TopicList.tpl5
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/controls/id/TopicList.tpl7
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/controls/ja/TopicList.tpl7
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/controls/pl/TopicList.tpl5
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/controls/zh/TopicList.tpl5
-rw-r--r--[-rwxr-xr-x]demos/quickstart/protected/pages/GettingStarted/CommandLine.page30
-rw-r--r--demos/quickstart/protected/pages/GettingStarted/Wsat.page64
-rw-r--r--demos/quickstart/protected/pages/GettingStarted/wsat_generate_ar.pngbin0 -> 75503 bytes
-rw-r--r--demos/quickstart/protected/pages/GettingStarted/wsat_login.pngbin0 -> 47951 bytes
-rw-r--r--framework/Data/Common/Mssql/TMssqlMetaData.php30
-rw-r--r--framework/Data/Common/Mysql/TMysqlMetaData.php16
-rw-r--r--framework/Data/Common/Oracle/TOracleMetaData.php38
-rw-r--r--framework/Data/Common/Pgsql/TPgsqlMetaData.php28
-rw-r--r--framework/Data/Common/Sqlite/TSqliteMetaData.php30
-rw-r--r--framework/Data/Common/TDbMetaData.php10
-rw-r--r--framework/Wsat/TWsatARGenerator.php283
-rw-r--r--framework/Wsat/TWsatService.php81
-rw-r--r--framework/Wsat/pages/TWsatGenerateAR.page56
-rw-r--r--framework/Wsat/pages/TWsatGenerateAR.php57
-rw-r--r--framework/Wsat/pages/TWsatHome.page17
-rw-r--r--framework/Wsat/pages/TWsatHome.php17
-rw-r--r--framework/Wsat/pages/TWsatLogin.page45
-rw-r--r--framework/Wsat/pages/TWsatLogin.php33
-rw-r--r--framework/Wsat/pages/TWsatScaffolding.php17
-rw-r--r--framework/Wsat/pages/config.xml9
-rw-r--r--framework/Wsat/pages/layout/TWsatLayout.php36
-rw-r--r--framework/Wsat/themes/PradoSoft/main.css152
-rw-r--r--nbproject/project.properties7
-rw-r--r--nbproject/project.xml13
34 files changed, 1110 insertions, 125 deletions
diff --git a/demos/blog-tutorial/protected/pages/Day2/CreateAR.page b/demos/blog-tutorial/protected/pages/Day2/CreateAR.page
index 1d7838a2..0cf28bdd 100755..100644
--- a/demos/blog-tutorial/protected/pages/Day2/CreateAR.page
+++ b/demos/blog-tutorial/protected/pages/Day2/CreateAR.page
@@ -17,60 +17,55 @@ To better organize our directories, we create a new directory <tt>protected/data
</com:TTextHighlighter>
<p>
-Instead of writing the classes manually, we will use the <a href="http://www.pradosoft.com/demos/quickstart/?page=GettingStarted.CommandLine">PRADO command line tool</a> again to generate the classes for us.
+Instead of writing the classes manually, we will use the <a href="?page=GettingStarted.Wsat">PRADO Web Site Administration Tool</a> to generate the classes for us.
+So we need to modify again our application configuration in the services section like follows:
</p>
-<p>
-Under the <tt>blog</tt> directory, run the following command to enter into the interactive mode of the command line tool:
-</p>
-
-<com:TTextHighlighter CssClass="source cli" Language="text">
-php path/to/prado-cli.php shell .
+ <p class="block-content">
+<com:TTextHighlighter CssClass="source" Language="xml">
+<services>
+ ...
+ <service id="wsat" class="System.Wsat.TWsatService" Password="my_secret_password" />
+</services>
</com:TTextHighlighter>
-
-<p>
-We should see
</p>
-<com:TTextHighlighter CssClass="source cli" Language="text">
-Command line tools for Prado 3.1.0.
-** Loaded PRADO appplication in directory "protected".
-PHP-Shell - Version 0.3.1
-(c) 2006, Jan Kneschke <jan@kneschke.de>
-
->> use '?' to open the inline help
-
->>
-</com:TTextHighlighter>
-
-<p>
-At the prompt, enter the following two commands to create <tt>UserRecord</tt> and <tt>PostRecord</tt> classes:
+<p class="block-content">
+ Then you are ready to go to: http://localhost/yoursite/index.php?wsat=TWsatLogin where you should see
+ the following page:
+</p>
+<img src="<%~wsat_login.png%>" style="width: 700px;" />
+<p class="block-content">
+ In the text field you need to type the password previosly specified in the service inclusion. This
+ is part of a basic security system to avoid undesirable persons to use this tool.
</p>
-<com:TTextHighlighter CssClass="source cli" Language="text">
->> generate users Application.database.UserRecord
-
->> generate posts Application.database.PostRecord
-</com:TTextHighlighter>
+ <p class="block-content">
+ In order to generate AR classes you need to go to: http://localhost/divermania/index.php?wsat=TWsatGenerateAR
+ by clicking the proper links in the welcome page. Then you should see the following page:
+</p>
+<img src="<%~blog_wsat_generate_ar.png%>" style="width: 700px;" />
<p>
-Here we used the <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Components">namespace format</a> again to specify the classes to be created. The path <tt>Application.database.UserRecord</tt> indicates that we want the <tt>UserRecord</tt> class file to be <tt>protected/database/UserRecord.php</tt>.
+ In the <tt>Output Folder</tt> field we used the <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Components">namespace format</a> again, the path <tt>Application.database</tt> indicates that we want to put our class's files in the <tt>protected/database/</tt> folder.
+ The <tt>*</tt> in the <tt>Table Name</tt> field means that we want to generate all AR classes, you can specify a table name instead if you want to generate just a specific AR class.
</p>
<p>
-We should see the following directory structure with two new files under <tt>protected/database</tt>:
+Afterward we should see the following directory structure with two new files under <tt>protected/database</tt>:
</p>
<img src="<%~ directories2.gif %>" class="output" />
<p>
-If we check the <tt>PostRecord</tt> class file, we should see the following content.
+If we check the <tt>PostRecord</tt> class file, we should see something similar to the following content:
</p>
<com:TTextHighlighter CssClass="source" Language="php">
class PostRecord extends TActiveRecord
{
const TABLE='posts';
+
public $post_id;
public $author_id;
public $create_time;
@@ -82,6 +77,15 @@ class PostRecord extends TActiveRecord
{
return parent::finder($className);
}
+
+ public static $RELATIONS = array (
+ 'author' => array(self::BELONGS_TO, 'UserRecord', 'author_id')
+ );
+
+ public function __toString()
+ {
+ return $this->title;
+ }
}
</com:TTextHighlighter>
@@ -89,29 +93,6 @@ class PostRecord extends TActiveRecord
As we see, for each field in the <tt>posts</tt> table, the class has a corresponding data member. The constant <tt>TABLE</tt> specifies the table name for the <tt>PostRecord</tt>. The static method <tt>finder()</tt> allows us to perform query and retrieve post data in terms of <tt>PostRecord</tt> objects.
</p>
-<p>
-We can use the command line tool to do some testing with our newly created Active Record classes. Still in the interactive mode of the command line tool, we enter a PHP statement and should see the following. Interested readers may try some other PHP statements, such as <tt>UserRecord::finder()->findAll()</tt>.
-</p>
-
-<com:TTextHighlighter CssClass="source cli" Language="text">
->> PostRecord::finder()->findAll()
-array
-(
- [0] => PostRecord#1
- (
- [post_id] => '1'
- [author_id] => 'admin'
- [create_time] => '1175708482'
- [title] => 'first post'
- [content] => 'this is my first post'
- [status] => '0'
- [TActiveRecord:_readOnly] => false
- [TActiveRecord:_connection] => null
- [TComponent:_e] => array()
- )
-)
-</com:TTextHighlighter>
-
<h1>Relationship Between Posts and Users</h1>
<p>
Recall that there was a foreign key relationship between the <tt>users</tt> and <tt>posts</tt> table. The entity-relationship diagram is shown below for convienence.
@@ -124,41 +105,9 @@ From the entity-relationship diagram above, we see that the <tt>posts</tt> table
</p>
<p>
-We can model the relationship between <tt>posts</tt> and <tt>users</tt> table in Active Record by modifying the <tt>PostRecord</tt> and <tt>UserRecord</tt> classes as follows.
+The static <tt>$RELATIONS</tt> property of <tt>PostRecord</tt> defines that the property <tt>$author</tt> belongs to an <tt>UserRecord</tt>. In <tt>array(self::BELONGS_TO, 'UserRecord')</tt>, the first element defines the relationship type, in this case <tt>self::BELONGS_TO</tt>. The second element is the name of related record, in this case an <tt>UserRecord</tt>.
</p>
-<com:TTextHighlighter CssClass="source" Language="php">
-class PostRecord extends TActiveRecord
-{
- //... properties and methods as before
-
- public $author; //holds an UserRecord
-
- public static $RELATIONS=array
- (
- 'author' => array(self::BELONGS_TO, 'UserRecord'),
- );
-}
-</com:TTextHighlighter>
-
-<p>
-The static <tt>$RELATIONS</tt> property of <tt>PostRecord</tt> defines that the property <tt>$author</tt> belongs to an <tt>UserRecord</tt>. In <tt>array(self::BELONGS_TO, 'UserRecord')</tt>, the first element defines the relationship type, in this case <tt>self::BELONGS_TO</tt>. The second element is the name of related record, in this case an <tt>UserRecord</tt>. The <tt>UserRecord</tt> is defined similarly below, the difference is that, the user record has many <tt>PostRecord</tt>s.
-</p>
-
-<com:TTextHighlighter CssClass="source" Language="php">
-class UserRecord extends TActiveRecord
-{
- //... properties and methods as before
-
- public $posts=array(); //holds an array of PostRecord
-
- public static $RELATIONS=array
- (
- 'posts' => array(self::HAS_MANY, 'PostRecord'),
- );
-}
-</com:TTextHighlighter>
-
<p>
An array of <tt>UserRecord</tt> with and its corresponding posts may be fetched as follows.
</p>
diff --git a/demos/blog-tutorial/protected/pages/Day2/blog_wsat_generate_ar.png b/demos/blog-tutorial/protected/pages/Day2/blog_wsat_generate_ar.png
new file mode 100644
index 00000000..433c1230
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/blog_wsat_generate_ar.png
Binary files differ
diff --git a/demos/blog-tutorial/protected/pages/Day2/wsat_login.png b/demos/blog-tutorial/protected/pages/Day2/wsat_login.png
new file mode 100644
index 00000000..dbe1ad8b
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/wsat_login.png
Binary files differ
diff --git a/demos/quickstart/protected/controls/TopicList.tpl b/demos/quickstart/protected/controls/TopicList.tpl
index adcdff4a..edc0ff3b 100755..100644
--- a/demos/quickstart/protected/controls/TopicList.tpl
+++ b/demos/quickstart/protected/controls/TopicList.tpl
@@ -8,6 +8,8 @@
<li><a href="?page=GettingStarted.Installation">Installation</a></li>
<li><a href="?page=GettingStarted.NewFeatures">New Features</a></li>
<li><a href="?page=GettingStarted.Upgrading">Upgrading from v2.x and v1.x</a></li>
+ <li><a href="?page=GettingStarted.Wsat">Web Site Administration Tool</a></li>
+ <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
</ul>
</div>
@@ -17,9 +19,8 @@
<li><a href="?page=GettingStarted.HelloWorld">Creating First PRADO Application</a></li>
<li><a href="?page=Fundamentals.Hangman">Sample: Hangman Game</a></li>
<li><a href="?page=Tutorial.CurrencyConverter">Currency Converter</a></li>
- <li><a href="?page=Tutorial.AddressBook">Address Book</a></li>
- <li><a href="?page=Tutorial.AjaxChat">AJAX Chat Client</a></li>
- <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
+ <li><a href="?page=Tutorial.AddressBook">Address Book</a></li>
+ <li><a href="?page=Tutorial.AjaxChat">AJAX Chat Client</a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/controls/es/TopicList.tpl b/demos/quickstart/protected/controls/es/TopicList.tpl
index be4be752..c2725733 100755..100644
--- a/demos/quickstart/protected/controls/es/TopicList.tpl
+++ b/demos/quickstart/protected/controls/es/TopicList.tpl
@@ -8,6 +8,8 @@
<li><a href="?page=GettingStarted.Installation">Instalación</a></li>
<li><a href="?page=GettingStarted.NewFeatures">Nuevas Funcionalidades</a></li>
<li><a href="?page=GettingStarted.Upgrading">Actualizar desde la version v2.x y v1.x</a></li>
+ <li><a href="?page=GettingStarted.Wsat">Web Site Administration Tool</a></li>
+ <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
</ul>
</div>
@@ -17,9 +19,8 @@
<li><a href="?page=GettingStarted.HelloWorld">Crear la primera aplicacion en PRADO</a></li>
<li><a href="?page=Fundamentals.Hangman">Ejemplo: El ahorcado</a></li>
<li><a href="?page=Tutorial.CurrencyConverter">Convertidor de Monedas</a></li>
- <li><a href="?page=Tutorial.AddressBook">Libreta de direcciones</a></li>
- <li><a href="?page=Tutorial.AjaxChat">Cliente Chat en AJAX </a></li>
- <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
+ <li><a href="?page=Tutorial.AddressBook">Libreta de direcciones</a></li>
+ <li><a href="?page=Tutorial.AjaxChat">Cliente Chat en AJAX </a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/controls/fr/TopicList.tpl b/demos/quickstart/protected/controls/fr/TopicList.tpl
index 44bb0b16..3020b24f 100755..100644
--- a/demos/quickstart/protected/controls/fr/TopicList.tpl
+++ b/demos/quickstart/protected/controls/fr/TopicList.tpl
@@ -8,6 +8,8 @@
<li><a href="?page=GettingStarted.Installation">Installation</a></li>
<li><a href="?page=GettingStarted.NewFeatures">Nouvelles fonctionnalités</a></li>
<li><a href="?page=GettingStarted.Upgrading">Mise à jour de v2.x et v1.x</a></li>
+ <li><a href="?page=GettingStarted.Wsat">Web Site Administration Tool</a></li>
+ <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
</ul>
</div>
@@ -17,8 +19,7 @@
<li><a href="?page=GettingStarted.HelloWorld">Créer sa première application PRADO</a></li>
<li><a href="?page=Fundamentals.Hangman">Exemple : Jeu du pendu</a></li>
<li><a href="?page=Tutorial.CurrencyConverter">Convertisseur monétaire</a></li>
- <li><a href="?page=Tutorial.AjaxChat">Chat AJAX</a></li>
- <li><a href="?page=GettingStarted.CommandLine">Outil en ligne de commande</a></li>
+ <li><a href="?page=Tutorial.AjaxChat">Chat AJAX</a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/controls/id/TopicList.tpl b/demos/quickstart/protected/controls/id/TopicList.tpl
index bfc6ed64..75fa8614 100755..100644
--- a/demos/quickstart/protected/controls/id/TopicList.tpl
+++ b/demos/quickstart/protected/controls/id/TopicList.tpl
@@ -8,6 +8,8 @@
<li><a href="?page=GettingStarted.Installation">Instalasi</a></li>
<li><a href="?page=GettingStarted.NewFeatures">Fitur Baru</a></li>
<li><a href="?page=GettingStarted.Upgrading">Meningkatkan dari v2.x dan v1.x</a></li>
+ <li><a href="?page=GettingStarted.Wsat">Web Site Administration Tool</a></li>
+ <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
</ul>
</div>
@@ -17,9 +19,8 @@
<li><a href="?page=GettingStarted.HelloWorld">Membuat Aplikasi PRADO Pertama</a></li>
<li><a href="?page=Fundamentals.Hangman">Contoh: Permainan Hangman</a></li>
<li><a href="?page=Tutorial.CurrencyConverter">Pengubah Kurs</a></li>
- <li><a href="?page=Tutorial.AddressBook">Buku Alamat</a></li>
- <li><a href="?page=Tutorial.AjaxChat">Klient Obrolan AJAX</a></li>
- <li><a href="?page=GettingStarted.CommandLine">Piranti Baris Perintah</a></li>
+ <li><a href="?page=Tutorial.AddressBook">Buku Alamat</a></li>
+ <li><a href="?page=Tutorial.AjaxChat">Klient Obrolan AJAX</a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/controls/ja/TopicList.tpl b/demos/quickstart/protected/controls/ja/TopicList.tpl
index ccaf5c63..dbfc7eb4 100755..100644
--- a/demos/quickstart/protected/controls/ja/TopicList.tpl
+++ b/demos/quickstart/protected/controls/ja/TopicList.tpl
@@ -8,6 +8,8 @@
<li><a href="?page=GettingStarted.Installation">インストール</a></li>
<li><a href="?page=GettingStarted.NewFeatures">新機能</a></li>
<li><a href="?page=GettingStarted.Upgrading">v2.x v1.x からのバージョンアップ</a></li>
+ <li><a href="?page=GettingStarted.Wsat">Web Site Administration Tool</a></li>
+ <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
</ul>
</div>
@@ -17,9 +19,8 @@
<li><a href="?page=GettingStarted.HelloWorld">初めての PRADO アプリケーション</a></li>
<li><a href="?page=Fundamentals.Hangman">Hangman ゲームサンプル</a></li>
<li><a href="?page=Tutorial.CurrencyConverter">通貨コンバーター</a></li>
- <li><a href="?page=Tutorial.AddressBook">アドレス帳</a></li>
- <li><a href="?page=Tutorial.AjaxChat">Ajax チャット</a></li>
- <li><a href="?page=GettingStarted.CommandLine">コマンドラインツール</a></li>
+ <li><a href="?page=Tutorial.AddressBook">アドレス帳</a></li>
+ <li><a href="?page=Tutorial.AjaxChat">Ajax チャット</a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/controls/pl/TopicList.tpl b/demos/quickstart/protected/controls/pl/TopicList.tpl
index 93052b36..33d8a126 100755..100644
--- a/demos/quickstart/protected/controls/pl/TopicList.tpl
+++ b/demos/quickstart/protected/controls/pl/TopicList.tpl
@@ -8,6 +8,8 @@
<li><a href="?page=GettingStarted.Installation">Instalacja</a></li>
<li><a href="?page=GettingStarted.NewFeatures">Nowe możliwości</a></li>
<li><a href="?page=GettingStarted.Upgrading">Aktualizacja z wersji 2.x oraz 1.x</a></li>
+ <li><a href="?page=GettingStarted.Wsat">Web Site Administration Tool</a></li>
+ <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
</ul>
</div>
@@ -18,8 +20,7 @@
<li><a href="?page=Fundamentals.Hangman">Przykład: gra wisielec</a></li>
<li><a href="?page=Tutorial.CurrencyConverter">Konwenter walut</a></li>
<li><a href="?page=Tutorial.AddressBook">Książka adresowa</a></li>
- <li><a href="?page=Tutorial.AjaxChat">AJAX-owy klient czat</a></li>
- <li><a href="?page=GettingStarted.CommandLine">Narzędzie linii poleceń</a></li>
+ <li><a href="?page=Tutorial.AjaxChat">AJAX-owy klient czat</a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/controls/zh/TopicList.tpl b/demos/quickstart/protected/controls/zh/TopicList.tpl
index 00fa2280..6a4c6e17 100755..100644
--- a/demos/quickstart/protected/controls/zh/TopicList.tpl
+++ b/demos/quickstart/protected/controls/zh/TopicList.tpl
@@ -8,6 +8,8 @@
<li><a href="?page=GettingStarted.Installation">安装</a></li>
<li><a href="?page=GettingStarted.NewFeatures">版本新功能</a></li>
<li><a href="?page=GettingStarted.Upgrading">从v2.x和v1.x升级</a></li>
+ <li><a href="?page=GettingStarted.Wsat">Web Site Administration Tool</a></li>
+ <li><a href="?page=GettingStarted.CommandLine">Command Line Tool</a></li>
</ul>
</div>
@@ -17,8 +19,7 @@
<li><a href="?page=GettingStarted.HelloWorld">创建第一个PRADO应用</a></li>
<li><a href="?page=Fundamentals.Hangman">Hangman游戏</a></li>
<li><a href="?page=Tutorial.CurrencyConverter">货币转换程序</a></li>
- <li><a href="?page=Tutorial.AjaxChat">AJAX聊天程序</a></li>
- <li><a href="?page=GettingStarted.CommandLine">命令行工具</a></li>
+ <li><a href="?page=Tutorial.AjaxChat">AJAX聊天程序</a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/pages/GettingStarted/CommandLine.page b/demos/quickstart/protected/pages/GettingStarted/CommandLine.page
index 5f5dacb9..bc8f2f55 100755..100644
--- a/demos/quickstart/protected/pages/GettingStarted/CommandLine.page
+++ b/demos/quickstart/protected/pages/GettingStarted/CommandLine.page
@@ -103,4 +103,34 @@ PostRecord#1
)
</com:TTextHighlighter>
</p>
+
+<h2>Creating Active Record Classes</h2>
+<p>
+In the blog demo project, we need to create two <a href="?page=Database.ActiveRecord">Active Record</a> classes, <tt>UserRecord</tt> and <tt>PostRecord</tt>, to represent data records in the <tt>users</tt> and <tt>posts</tt> tables, respectively. Active Record classes must extend from the base class <tt>ActiveRecord</tt>, and must define property names that matches with the field names of the corresponding table.
+</p>
+
+<p>
+To better organize our directories, we create a new directory <tt>protected/database</tt> to hold the class files. We also modify our application configuration by inserting the following lines. It is equivalent to adding the directory <tt>protected/database</tt> to PHP include_path, which allows us to use the classes without explicitly including them.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+<paths>
+ <using namespace="Application.database.*" />
+</paths>
+</com:TTextHighlighter>
+
+<p>
+At the prompt, enter the following two commands to create <tt>UserRecord</tt> and <tt>PostRecord</tt> classes:
+</p>
+
+<com:TTextHighlighter CssClass="source cli" Language="text">
+>> generate users Application.database.UserRecord
+
+>> generate posts Application.database.PostRecord
+</com:TTextHighlighter>
+
+<p>
+Here we used the <a href="?page=Fundamentals.Components">namespace format</a> again to specify the classes to be created. The path <tt>Application.database.UserRecord</tt> indicates that we want the <tt>UserRecord</tt> class file to be <tt>protected/database/UserRecord.php</tt>.
+</p>
+
</com:TContent>
diff --git a/demos/quickstart/protected/pages/GettingStarted/Wsat.page b/demos/quickstart/protected/pages/GettingStarted/Wsat.page
new file mode 100644
index 00000000..3d07e6f2
--- /dev/null
+++ b/demos/quickstart/protected/pages/GettingStarted/Wsat.page
@@ -0,0 +1,64 @@
+<com:TContent ID="body">
+ <h1>Web Site Administration Tool</h1>
+ <p class="block-content">
+ Web Site Administration Tool (WSAT) is a development tool which allows you to perform several
+ tedious tasks of a PRADO project in a GUI fashion. Its inspired in both Asp.Net - Web Site Administration Tool and Yii's Gii.
+ WSAT will continue gaining new features along the time, at the moment it bring you the followings:
+
+ <ul>
+ <li>Generate one or all <a href="?page=Database.ActiveRecord">Active Record Classes.</a></li>
+ <li>Optionally generate all relationships in Active Record Classes.</li>
+ <li>Generate the magic __toString() method in all AR Classes.</li>
+ </ul>
+ </p>
+
+ <h2>Requirements</h2>
+ <p class="block-content">
+ To use WSAT, you need to add in your project configuration file: <tt>application.xml</tt>,
+ in the services section the wsat service like follows:
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+<services>
+ ...
+ <service id="wsat" class="System.Wsat.TWsatService" Password="my_secret_password" />
+</services>
+</com:TTextHighlighter>
+ </p>
+
+ <h2>Usage</h2>
+ <p class="block-content">
+ Then you are ready to go to: http://localhost/yoursite/index.php?wsat=TWsatLogin and doing so you should see
+ the following page:
+ </p>
+ <img src="<%~wsat_login.png%>" style="width: 700px;" />
+ <p class="block-content">
+ Where in the text field you need to type the password previosly specified in the service inclusion. This
+ is part of a basic security system to avoid undesirable persons to use this tool.
+ </p>
+
+ <h2>Active Record classes generation</h2>
+ <p class="block-content">
+ In order to generate AR classes you need to go to: http://localhost/divermania/index.php?wsat=TWsatGenerateAR
+ by clicking the proper links in the welcome page. Then you should see the following page:
+ </p>
+ <img src="<%~wsat_generate_ar.png%>" style="width: 700px;" />
+ <p class="block-content">
+ In which you can find a basic usage documentation in a light green panel
+ and then some proper fields in order to generate active record classes. These fields are:
+ </p>
+
+ <ul>
+ <li><b>Table Name: </b> refers to the table name in your database for which you want to generate an AR class.
+ Let it as come by default with an * to generate them all.</li>
+ <li><b>Output Folder: </b> refers to the folder where you want to save your generated classes.
+ It only accepts namespace format which means that you need to specify your path separated with points in between.
+ It default value is: "Application.App_Data.AR_Classes" which references the protected/App_Data/AR_Classes
+ file of your project, if you haven't created them yet and you want to, don't bother, WSAT will do it for you.</li>
+ <li><b>Class Prefix: </b> refers to the prefix that you whish to specify in front of every class name.
+ Clear the field to specify no prefix.</li>
+ <li><b>Class Suffix: </b> refers to the suffix that you whish to specify at the end of every class name.
+ Clear the field to specify no suffix.</li>
+ <li><b>Build Relations: </b> whether or not you want to add relationships to AR classes generation.</li>
+ </ul>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/GettingStarted/wsat_generate_ar.png b/demos/quickstart/protected/pages/GettingStarted/wsat_generate_ar.png
new file mode 100644
index 00000000..8f0f59e7
--- /dev/null
+++ b/demos/quickstart/protected/pages/GettingStarted/wsat_generate_ar.png
Binary files differ
diff --git a/demos/quickstart/protected/pages/GettingStarted/wsat_login.png b/demos/quickstart/protected/pages/GettingStarted/wsat_login.png
new file mode 100644
index 00000000..dbe1ad8b
--- /dev/null
+++ b/demos/quickstart/protected/pages/GettingStarted/wsat_login.png
Binary files differ
diff --git a/framework/Data/Common/Mssql/TMssqlMetaData.php b/framework/Data/Common/Mssql/TMssqlMetaData.php
index 3ff7ac7f..8ee455d5 100644
--- a/framework/Data/Common/Mssql/TMssqlMetaData.php
+++ b/framework/Data/Common/Mssql/TMssqlMetaData.php
@@ -25,7 +25,7 @@ Prado::using('System.Data.Common.Mssql.TMssqlTableInfo');
* @since 3.1
*/
class TMssqlMetaData extends TDbMetaData
-{
+{
/**
* @return string TDbTableInfo class name.
*/
@@ -260,5 +260,33 @@ EOD;
}
return false;
}
+
+ /**
+ * Returns all table names in the database.
+ * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
+ * If not empty, the returned table names will be prefixed with the schema name.
+ * @return array all table names in the database.
+ */
+ public function findTableNames($schema='dbo')
+ {
+ $condition="TABLE_TYPE='BASE TABLE'";
+ $sql=<<<EOD
+SELECT TABLE_NAME, TABLE_SCHEMA FROM [INFORMATION_SCHEMA].[TABLES]
+WHERE TABLE_SCHEMA=:schema AND $condition
+EOD;
+ $command=$this->getDbConnection()->createCommand($sql);
+ $command->bindParam(":schema", $schema);
+ $rows=$command->queryAll();
+ $names=array();
+ foreach ($rows as $row)
+ {
+ if ($schema == self::DEFAULT_SCHEMA)
+ $names[]=$row['TABLE_NAME'];
+ else
+ $names[]=$schema.'.'.$row['TABLE_SCHEMA'].'.'.$row['TABLE_NAME'];
+ }
+
+ return $names;
+ }
}
diff --git a/framework/Data/Common/Mysql/TMysqlMetaData.php b/framework/Data/Common/Mysql/TMysqlMetaData.php
index 9dc995fc..f08a6fc0 100644
--- a/framework/Data/Common/Mysql/TMysqlMetaData.php
+++ b/framework/Data/Common/Mysql/TMysqlMetaData.php
@@ -382,5 +382,21 @@ EOD;
}
return false;
}
+
+ /**
+ * Returns all table names in the database.
+ * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
+ * If not empty, the returned table names will be prefixed with the schema name.
+ * @return array all table names in the database.
+ */
+ public function findTableNames($schema='')
+ {
+ if($schema==='')
+ return $this->getDbConnection()->createCommand('SHOW TABLES')->queryColumn();
+ $names=$this->getDbConnection()->createCommand('SHOW TABLES FROM '.$this->quoteTableName($schema))->queryColumn();
+ foreach($names as &$name)
+ $name=$schema.'.'.$name;
+ return $names;
+ }
}
diff --git a/framework/Data/Common/Oracle/TOracleMetaData.php b/framework/Data/Common/Oracle/TOracleMetaData.php
index 793070ed..8648fcc9 100644
--- a/framework/Data/Common/Oracle/TOracleMetaData.php
+++ b/framework/Data/Common/Oracle/TOracleMetaData.php
@@ -336,5 +336,41 @@ EOD;
}
return false;
}
-}
+
+ /**
+ * Returns all table names in the database.
+ * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
+ * If not empty, the returned table names will be prefixed with the schema name.
+ * @return array all table names in the database.
+ */
+ public function findTableNames($schema='')
+ {
+ if($schema==='')
+ {
+ $sql=<<<EOD
+SELECT table_name, '{$schema}' as table_schema FROM user_tables
+EOD;
+ $command=$this->getDbConnection()->createCommand($sql);
+ }
+ else
+ {
+ $sql=<<<EOD
+SELECT object_name as table_name, owner as table_schema FROM all_objects
+WHERE object_type = 'TABLE' AND owner=:schema
+EOD;
+ $command=$this->getDbConnection()->createCommand($sql);
+ $command->bindParam(':schema',$schema);
+ }
+ $rows=$command->queryAll();
+ $names=array();
+ foreach($rows as $row)
+ {
+ if($schema===$this->getDefaultSchema() || $schema==='')
+ $names[]=$row['TABLE_NAME'];
+ else
+ $names[]=$row['TABLE_SCHEMA'].'.'.$row['TABLE_NAME'];
+ }
+ return $names;
+ }
+} \ No newline at end of file
diff --git a/framework/Data/Common/Pgsql/TPgsqlMetaData.php b/framework/Data/Common/Pgsql/TPgsqlMetaData.php
index dd91dfdc..a8e7bfed 100644
--- a/framework/Data/Common/Pgsql/TPgsqlMetaData.php
+++ b/framework/Data/Common/Pgsql/TPgsqlMetaData.php
@@ -418,5 +418,33 @@ EOD;
}
return false;
}
+
+ /**
+ * Returns all table names in the database.
+ * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
+ * If not empty, the returned table names will be prefixed with the schema name.
+ * @return array all table names in the database.
+ */
+ public function findTableNames($schema='public')
+ {
+ if($schema==='')
+ $schema=self::DEFAULT_SCHEMA;
+ $sql=<<<EOD
+SELECT table_name, table_schema FROM information_schema.tables
+WHERE table_schema=:schema AND table_type='BASE TABLE'
+EOD;
+ $command=$this->getDbConnection()->createCommand($sql);
+ $command->bindParam(':schema',$schema);
+ $rows=$command->queryAll();
+ $names=array();
+ foreach($rows as $row)
+ {
+ if($schema===self::DEFAULT_SCHEMA)
+ $names[]=$row['table_name'];
+ else
+ $names[]=$row['table_schema'].'.'.$row['table_name'];
+ }
+ return $names;
+ }
}
diff --git a/framework/Data/Common/Sqlite/TSqliteMetaData.php b/framework/Data/Common/Sqlite/TSqliteMetaData.php
index 3d789500..c66825c7 100644
--- a/framework/Data/Common/Sqlite/TSqliteMetaData.php
+++ b/framework/Data/Common/Sqlite/TSqliteMetaData.php
@@ -190,21 +190,15 @@ class TSqliteMetaData extends TDbMetaData
}
return false;
}
-}
-
-/**
-
-CREATE TABLE foo
-(
- id INTEGER NOT NULL PRIMARY KEY,
- id2 CHAR(2)
-);
-
-CREATE TABLE bar
-(
- id INTEGER NOT NULL PRIMARY KEY,
- foo_id INTEGER
- CONSTRAINT fk_foo_id REFERENCES foo(id) ON DELETE CASCADE
-);
-*/
-
+
+ /**
+ * Returns all table names in the database.
+ * @param string $schema the schema of the tables. This is not used for sqlite database.
+ * @return array all table names in the database.
+ */
+ public function findTableNames($schema='')
+ {
+ $sql="SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence'";
+ return $this->getDbConnection()->createCommand($sql)->queryColumn();
+ }
+} \ No newline at end of file
diff --git a/framework/Data/Common/TDbMetaData.php b/framework/Data/Common/TDbMetaData.php
index 2ad5c592..0a3a6e90 100644
--- a/framework/Data/Common/TDbMetaData.php
+++ b/framework/Data/Common/TDbMetaData.php
@@ -180,5 +180,15 @@ abstract class TDbMetaData extends TComponent
return $lft . str_replace(self::$delimiterIdentifier, '', $name) . $rgt;
}
+
+ /**
+ * Returns all table names in the database.
+ * This method should be overridden by child classes in order to support this feature
+ * because the default implementation simply throws an exception.
+ * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema.
+ * If not empty, the returned table names will be prefixed with the schema name.
+ * @return array all table names in the database.
+ */
+ abstract public function findTableNames($schema='');
}
diff --git a/framework/Wsat/TWsatARGenerator.php b/framework/Wsat/TWsatARGenerator.php
new file mode 100644
index 00000000..7ae5e46e
--- /dev/null
+++ b/framework/Wsat/TWsatARGenerator.php
@@ -0,0 +1,283 @@
+<?php
+
+/**
+ * @author Daniel Sampedro Bello <darthdaniel85@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2013 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @since 3.3
+ * @package Wsat
+ */
+
+Prado::using('System.Data.Common.TDbMetaData');
+
+class TWsatARGenerator
+{
+
+ /**
+ * @return TDbMetaData for retrieving metadata information, such as
+ * table and columns information, from a database connection.
+ */
+ private $_dbMetaData;
+
+ /**
+ * Output folder where AR classes will be saved.
+ */
+ private $_opFile;
+
+ /**
+ * Class name prefix
+ */
+ private $_clasPrefix;
+
+ /**
+ * Class name sufix
+ */
+ private $_classSufix;
+
+ /**
+ * all table relations array
+ */
+ private $_relations;
+
+ /**
+ * unquote chars
+ * @var array
+ */
+ private $uqChars = array('[', ']', '"', '`', "'");
+
+ function __construct()
+ {
+ if(!class_exists("TActiveRecordManager", false))
+ throw new Exception("You need to enable the ActiveRecord module in your application configuration file.");
+ $ar_manager = TActiveRecordManager::getInstance();
+ $_conn = $ar_manager->getDbConnection();
+ $_conn->Active = true;
+ $this->_dbMetaData = TDbMetaData::getInstance($_conn);
+ }
+
+ public function setOpFile($op_file_namespace)
+ {
+ $op_file = Prado::getPathOfNamespace($op_file_namespace);
+ if (empty($op_file))
+ throw new Exception("You need to fix your output folder namespace.");
+ if (!is_dir($op_file))
+ mkdir($op_file, 0777, true);
+ $this->_opFile = $op_file;
+ }
+
+ public function setClasPrefix($_clas_prefix)
+ {
+ $this->_clasPrefix = $_clas_prefix;
+ }
+
+ public function setClassSufix($_clas_sufix)
+ {
+ $this->_classSufix = $_clas_sufix;
+ }
+
+//-----------------------------------------------------------------------------
+ // <editor-fold defaultstate="collapsed" desc="Main APIs">
+ public function generate($tableName)
+ {
+ $tableInfo = $this->_dbMetaData->getTableInfo($tableName);
+ $this->_commonGenerate($tableName, $tableInfo);
+ }
+
+ public function generateAll()
+ {
+ foreach ($this->_dbMetaData->findTableNames() as $tableName)
+ {
+ if ($tableName == "pradocache")
+ continue;
+ $tableInfo = $this->_dbMetaData->getTableInfo($tableName);
+ if (!empty($this->_relations))
+ {
+ // Cancel generation of M-M relationships middle table
+ if (count($tableInfo->getPrimaryKeys()) === 2 && count($tableInfo->getColumns()) === 2)//M-M relationships
+ continue;
+ }
+ $this->_commonGenerate($tableName, $tableInfo);
+ }
+ }
+
+ public function buildRelations()
+ {
+ $this->_relations = array();
+ foreach ($this->_dbMetaData->findTableNames() as $table_name)
+ {
+ $tableInfo = $this->_dbMetaData->getTableInfo($table_name);
+ $pks = $tableInfo->getPrimaryKeys();
+ $fks = $tableInfo->getForeignKeys();
+
+ if (count($pks) === 2 && count($tableInfo->getColumns()) === 2)//M-M relationships
+ {
+ $table_name_mm = $fks[0]["table"];
+ $table_name_mm2 = $fks[1]["table"];
+
+ $this->_relations[$table_name_mm][] = array(
+ "prop_name" => strtolower($table_name_mm2),
+ "rel_type" => "self::MANY_TO_MANY",
+ "ref_class_name" => $this->_getProperClassName($table_name_mm2),
+ "prop_ref" => $table_name
+ );
+
+ $this->_relations[$table_name_mm2][] = array(
+ "prop_name" => strtolower($table_name_mm),
+ "rel_type" => "self::MANY_TO_MANY",
+ "ref_class_name" => $this->_getProperClassName($table_name_mm),
+ "prop_ref" => $table_name
+ );
+ continue;
+ }
+ foreach ($fks as $fk_data)//1-M relationships
+ {
+ $owner_table = $fk_data["table"];
+ $slave_table = $table_name;
+ $fk_prop = key($fk_data["keys"]);
+
+ $this->_relations[$owner_table][] = array(
+ "prop_name" => strtolower($slave_table),
+ "rel_type" => "self::HAS_MANY",
+ "ref_class_name" => $this->_getProperClassName($slave_table),
+ "prop_ref" => $fk_prop
+ );
+
+ $this->_relations[$slave_table][] = array(
+ "prop_name" => strtolower($owner_table),
+ "rel_type" => "self::BELONGS_TO",
+ "ref_class_name" => $this->_getProperClassName($owner_table),
+ "prop_ref" => $fk_prop
+ );
+ }
+ }
+ }
+
+// </editor-fold>
+//-----------------------------------------------------------------------------
+ // <editor-fold defaultstate="collapsed" desc="Common Methods">
+
+ private function _commonGenerate($tableName, $tableInfo)
+ {
+ if (count($tableInfo->getColumns()) === 0)
+ throw new Exception("Unable to find table or view $tableName in " . $this->_dbMetaData->getDbConnection()->getConnectionString() . ".");
+ else
+ {
+ $properties = array();
+ foreach ($tableInfo->getColumns() as $field => $column)
+ $properties[] = $this->generateProperty($field, $column);
+ $toString = $this->_buildSmartToString($tableInfo);
+ }
+
+ $clasName = $this->_getProperClassName($tableName);
+ $class = $this->generateClass($properties, $tableName, $clasName, $toString);
+ $output = $this->_opFile . DIRECTORY_SEPARATOR . $clasName . ".php";
+ file_put_contents($output, $class);
+ }
+
+ private function _getProperClassName($tableName)
+ {
+ $table_name_words = str_replace("_", " ", strtolower($tableName));
+ $final_conversion = str_replace(" ", "", ucwords($table_name_words));
+ return $this->_clasPrefix . $final_conversion . $this->_classSufix;
+ }
+
+ public function renderAllTablesInformation()
+ {
+ foreach ($this->_dbMetaData->findTableNames() as $table_name)
+ {
+ echo $table_name . "<br>";
+
+ $tableInfo = $this->_dbMetaData->getTableInfo($table_name);
+ echo "Table info:" . "<br>";
+ echo "<pre>";
+ var_dump($tableInfo);
+ echo "</pre>";
+ }
+ }
+
+//-----------------------------------------------------------------------------
+
+ protected function generateProperty($field, $column)
+ {
+ $prop = '';
+ $name = '$' . $field;
+
+ /* TODO use in version 2.0 */
+ // $type = $column->getPHPType();
+
+ $prop .= "\tpublic $name;";
+ return $prop;
+ }
+
+ private function _renderRelations($tablename)
+ {
+ if (!isset($this->_relations[$tablename]))
+ return "";
+
+ $code = "\tpublic static \$RELATIONS = array (";
+ foreach ($this->_relations[$tablename] as $rel_data)
+ $code .= "\n\t\t'" . $rel_data["prop_name"] . "' => array(" . $rel_data["rel_type"] . ", '" . $rel_data["ref_class_name"] . "', '" . $rel_data["prop_ref"] . "'),";
+
+ $code = substr($code, 0, -1);
+ $code .= "\n\t);";
+ return $code;
+ }
+
+ private function _buildSmartToString($tableInfo)
+ {
+ $code = "\tpublic function __toString() {";
+ $property = "throw new THttpException(500, 'Not implemented yet.');";
+ try
+ {
+ foreach ($tableInfo->getColumns() as $column)
+ {
+ if (isset($column->IsPrimaryKey) && $column->IsPrimaryKey)
+ $property = str_replace($this->uqChars, "", $column->ColumnName);
+ elseif ($column->PdoType == PDO::PARAM_STR && $column->DBType != "date")
+ {
+ $property = str_replace($this->uqChars, "", $column->ColumnName);
+ break;
+ }
+ }
+ } catch (Exception $ex)
+ {
+ Prado::trace($ex->getMessage());
+ }
+ $code .= "\n\t\treturn \$this->$property;";
+ $code .= "\n\t}";
+ return $code;
+ }
+
+ protected function generateClass($properties, $tablename, $classname, $toString)
+ {
+ $props = implode("\n", $properties);
+ $relations = $this->_renderRelations($tablename);
+ $date = date('Y-m-d h:i:s');
+ $env_user = getenv("username");
+ return <<<EOD
+<?php
+/**
+ * Auto generated by PRADO - WSAT on $date.
+ * @author $env_user
+ */
+class $classname extends TActiveRecord
+{
+ const TABLE='$tablename';
+
+$props
+
+ public static function finder(\$className=__CLASS__) {
+ return parent::finder(\$className);
+ }
+
+$relations
+
+$toString
+}
+EOD;
+ }
+
+// </editor-fold>
+} \ No newline at end of file
diff --git a/framework/Wsat/TWsatService.php b/framework/Wsat/TWsatService.php
new file mode 100644
index 00000000..63bfebc7
--- /dev/null
+++ b/framework/Wsat/TWsatService.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @author Daniel Sampedro Bello <darthdaniel85@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2013 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @since 3.3
+ * @package Wsat
+ */
+
+/**
+ * TWsatService class
+ *
+ * Wsat is inspired in both Asp.Net - Web Site Administration Tool(WSAT) and Yii's Gii.
+ * Wsat enables you to generate code saving your time in too many tedious tasks in a GUI fashion.
+ *
+ * Current options:
+ * 1- Generate one or all Active Record Classes from your DataBase.
+ * 1.1- Automatically generate all relations between the AR Classes (new).
+ * 1.2- Automatically generate the __toString() magic method in a smart way (new).
+ *
+ * To use TWsatService, configure it in the application configuration file like following:
+ * <code>
+ * <services>
+ * ...
+ * <service id="wsat" class="System.Wsat.TWsatService" Password="my_secret_password" />
+ * </services>
+ * </code>
+ * ...and then you need to go to http://localhost/yoursite/index.php?wsat=TWsatLogin
+ * and generate code and configure your site.
+ *
+ * Warning: You should only use Wsat in development mode.
+ */
+class TWsatService extends TPageService
+{
+
+ private $_pass = '';
+
+ public function init($config)
+ {
+ if ($this->getApplication()->getMode() === TApplicationMode::Performance || $this->getApplication()->getMode() === TApplicationMode::Normal)
+ throw new TInvalidOperationException("You should not use Prado WSAT in any of the production modes.");
+
+ if (empty($this->_pass))
+ throw new TConfigurationException("You need to specify the Password attribute.");
+
+ $this->setDefaultPage("TWsatHome");
+ $this->_startThemeManager();
+ parent::init($config);
+ }
+
+ public function getBasePath()
+ {
+ $basePath = Prado::getPathOfNamespace("System.Wsat.pages");
+ return realpath($basePath);
+ }
+
+ private function _startThemeManager()
+ {
+ $themeManager = new TThemeManager;
+ $themeManager->BasePath = "System.Wsat.themes";
+ $url = Prado::getApplication()->getAssetManager()->publishFilePath(Prado::getPathOfNamespace('System.Wsat'));
+ $themeManager->BaseUrl = "$url/themes";
+
+ $themeManager->init(null);
+ $this->setThemeManager($themeManager);
+ }
+
+ public function getPassword()
+ {
+ return $this->_pass;
+ }
+
+ public function setPassword($_pass)
+ {
+ $this->_pass = $_pass;
+ }
+
+} \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatGenerateAR.page b/framework/Wsat/pages/TWsatGenerateAR.page
new file mode 100644
index 00000000..926d6b0f
--- /dev/null
+++ b/framework/Wsat/pages/TWsatGenerateAR.page
@@ -0,0 +1,56 @@
+<com:TContent ID="Content">
+ <div style="margin: 10px; font-size: 16px; font-weight: bold">Active Record Classes Generator</div>
+ <div class="green_panel" style="text-align: left; font-size: 14px; margin: 15px 5px">
+ <label>This generator generates an AR class for the specified database table.</label><br/>
+ <label>Fields with <b style="color: red">*</b> are required.</label>
+ <hr/>
+ <div style="font-size: 12px; font-style: italic">
+ <ul>
+ <li>If you want to generate all AR Classes, keep the "Table Name" field as appears by default.</li>
+ <li>"Output Folder" field refers to the directory that the new AR class file should be generated under... where Application refers to the protected folder of your project. You can let this default field value and PRADO will create the proper folders for you.</li>
+ </ul>
+ </div>
+ </div>
+
+ <div style="font-size: 14px">
+ <div class="form_row">
+ <com:TLabel Text="Table Name:" ForControl="table_name" style="margin-right: 24px" />
+ <com:TTextBox ID="table_name" Text="*" CssClass="in_text" />
+ <label style="color: red">*</label>
+ <com:TRequiredFieldValidator ControlToValidate="table_name" Text="Table name cannot be blank." Display="Dynamic" />
+ </div>
+
+ <div class="form_row">
+ <com:TLabel Text="Output Folder:" ForControl="output_folder" style="margin-right: 8px"/>
+ <com:TTextBox ID="output_folder" Text="Application.App_Data.AR_Classes" CssClass="in_text" />
+ <label style="color: red">*</label>
+ <com:TRequiredFieldValidator ControlToValidate="output_folder" Text="Output folder cannot be blank." Display="Dynamic" />
+ </div>
+
+ <div class="form_row">
+ <com:TLabel Text="Class Prefix:" ForControl="class_prefix" style="margin-right: 25px"/>
+ <com:TTextBox ID="class_prefix" Text="AR_" CssClass="in_text" />
+ </div>
+
+ <div class="form_row">
+ <com:TLabel Text="Class Suffix:" ForControl="class_suffix" style="margin-right: 27px"/>
+ <com:TTextBox ID="class_suffix" CssClass="in_text" />
+ </div>
+
+ <div class="form_row">
+ <com:TLabel Text="Build Relations:" ForControl="build_rel"/>
+ <com:TCheckBox ID="build_rel" Checked="true" />
+ </div>
+
+ <com:TPanel ID="feedback_panel" Visible="false" style="width: 400px">
+ <com:TLabel ID="generation_msg" />
+ </com:TPanel>
+
+ <br/>
+ <div style="text-align: center; width: 400px">
+ <com:TButton Text="Preview" OnClick="preview" Visible="false" />
+ <com:TButton Text="Generate" OnClick="generate" />
+ </div>
+ </div>
+
+</com:TContent>
diff --git a/framework/Wsat/pages/TWsatGenerateAR.php b/framework/Wsat/pages/TWsatGenerateAR.php
new file mode 100644
index 00000000..f0ce8430
--- /dev/null
+++ b/framework/Wsat/pages/TWsatGenerateAR.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @author Daniel Sampedro Bello <darthdaniel85@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2013 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @since 3.3
+ * @package Wsat.pages
+ */
+Prado::using("System.Wsat.TWsatARGenerator");
+
+class TWsatGenerateAR extends TPage
+{
+
+ public function generate($sender)
+ {
+ if ($this->IsValid)
+ {
+ $tableName = $this->table_name->Text;
+ $outputFolderNs = $this->output_folder->Text;
+ $classPrefix = $this->class_prefix->Text;
+ $classSuffix = $this->class_suffix->Text;
+
+ try
+ {
+ $ar_generator = new TWsatARGenerator();
+ $ar_generator->setOpFile($outputFolderNs);
+ $ar_generator->setClasPrefix($classPrefix);
+ $ar_generator->setClassSufix($classSuffix);
+
+ if ($this->build_rel->Checked)
+ $ar_generator->buildRelations();
+
+ if ($tableName != "*")
+ $ar_generator->generate($tableName);
+ else
+ $ar_generator->generateAll();
+
+ $this->feedback_panel->CssClass = "green_panel";
+ $this->generation_msg->Text = "The code has been generated successfully.";
+ } catch (Exception $ex)
+ {
+ $this->feedback_panel->CssClass = "red_panel";
+ $this->generation_msg->Text = $ex->getMessage();
+ }
+ $this->feedback_panel->Visible = true;
+ }
+ }
+
+ public function preview($sender)
+ {
+// throw new THttpException(500, "Not implemented yet.");
+ }
+
+} \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatHome.page b/framework/Wsat/pages/TWsatHome.page
new file mode 100644
index 00000000..e8796ccd
--- /dev/null
+++ b/framework/Wsat/pages/TWsatHome.page
@@ -0,0 +1,17 @@
+<com:TContent ID="Content">
+ <label style="font-size: 18px; font-weight: bold">Welcome to the Web Site Administration Tool</label>
+
+ <div style="margin-top: 25px"><b>Application Dir:</b> <%= Prado::getPathOfNamespace('Application') %></div>
+
+ <br/>
+ <table>
+ <tr style="background-color: #cccccc">
+ <td style="padding: 5px; width: 100px">
+ <com:THyperLink NavigateUrl="<%= $this->Service->constructUrl('TWsatGenerateAR') %>" Text="AR Classes" />
+ </td>
+ <td style="padding: 5px">
+ Enables you to generate all Active Record Classes with relations included.
+ </td>
+ </tr>
+ </table>
+</com:TContent>
diff --git a/framework/Wsat/pages/TWsatHome.php b/framework/Wsat/pages/TWsatHome.php
new file mode 100644
index 00000000..b5ae1bb4
--- /dev/null
+++ b/framework/Wsat/pages/TWsatHome.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @author Daniel Sampedro Bello <darthdaniel85@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2013 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @since 3.3
+ * @package Wsat.pages
+ */
+Prado::using("System.Wsat.TWsatARGenerator");
+
+class TWsatHome extends TPage
+{
+
+} \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatLogin.page b/framework/Wsat/pages/TWsatLogin.page
new file mode 100644
index 00000000..79578f59
--- /dev/null
+++ b/framework/Wsat/pages/TWsatLogin.page
@@ -0,0 +1,45 @@
+<%@ MasterClass="" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <com:THead Title="PRADO - WSAT">
+ <com:TMetaTag HttpEquiv="Content-Type" Content="text/html; charset=utf-8" />
+ <com:TMetaTag HttpEquiv="Content-Language" Content="en" />
+ </com:THead>
+
+ <body>
+ <com:TForm>
+
+ <div id="header">
+ <a href="<%= $this->Service->DefaultPageUrl %>">
+ <div class="logo"></div>
+ <div style="float: left; margin-top: 17px">PRADO <br /> Web Site Administration Tool</div>
+ </a>
+ <div class="mantisbg"></div>
+ <div style="clear: both"></div>
+ </div>
+
+ <div class="mainmenu">
+ <div style="float: right"><com:THyperLink NavigateUrl="http://www.pradosoft.com/" Text="PradoSoft.com" Target="_blank" />&nbsp;|&nbsp;</div>
+ <div style="float: right"><com:THyperLink NavigateUrl="<%= $this->Service->DefaultPageUrl %>" Text="Web App" Target="_blank" />&nbsp;|&nbsp;</div>
+ <div style="float: right"><com:THyperLink NavigateUrl="http://www.pradosoft.com/forum/" Text="Help" Target="_blank" />&nbsp;|&nbsp;</div>
+ <div style="clear: both"></div>
+ </div>
+
+ <div class="login_form">
+ <com:TLabel Text="Please enter your password:" ForControl="password"/><br/>
+ <com:TTextBox ID="password" TextMode="Password" style="margin: 5px" /><br/>
+ <com:TRequiredFieldValidator ControlToValidate="password" ValidationGroup="loginGroup" Text="Password cannot be blank." Display="Dynamic" /><br/>
+ <com:TCustomValidator ControlToValidate="password" ValidationGroup="loginGroup" OnServerValidate="validatePassword" Text="Incorrect password." Display="Dynamic" />
+
+ <div><com:TButton Text="Enter" ValidationGroup="loginGroup" OnClick="login" /></div>
+ </div>
+
+ <div id="footer">
+ Copyright &copy; 2005-<%= date('Y') %> <a href="http://www.pradosoft.com">PradoSoft</a>.
+ <br/><br/>
+ <%= Prado::poweredByPrado() %>
+ </div>
+ </com:TForm>
+ </body>
+</html>
diff --git a/framework/Wsat/pages/TWsatLogin.php b/framework/Wsat/pages/TWsatLogin.php
new file mode 100644
index 00000000..21994c07
--- /dev/null
+++ b/framework/Wsat/pages/TWsatLogin.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @author Daniel Sampedro Bello <darthdaniel85@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2013 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @since 3.3
+ * @package Wsat.pages
+ */
+class TWsatLogin extends TPage
+{
+
+ public function login()
+ {
+ if ($this->IsValid)
+ {
+ $this->Session["wsat_password"] = $this->getService()->getPassword();
+
+ $url = $this->Service->constructUrl('TWsatHome');
+ $this->Response->redirect($url);
+ }
+ }
+
+ public function validatePassword($sender, $param)
+ {
+ $config_pass = $this->Service->Password;
+ $user_pass = $this->password->Text;
+ $param->IsValid = $user_pass === $config_pass;
+ }
+
+} \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatScaffolding.php b/framework/Wsat/pages/TWsatScaffolding.php
new file mode 100644
index 00000000..b8e28b03
--- /dev/null
+++ b/framework/Wsat/pages/TWsatScaffolding.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @author Daniel Sampedro Bello <darthdaniel85@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2013 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @since 3.3
+ * @package Wsat.pages
+ */
+Prado::using("System.Wsat.TWsatARGenerator");
+
+class TWsatScaffolding extends TPage
+{
+
+} \ No newline at end of file
diff --git a/framework/Wsat/pages/config.xml b/framework/Wsat/pages/config.xml
new file mode 100644
index 00000000..727e8eab
--- /dev/null
+++ b/framework/Wsat/pages/config.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+ <modules>
+ <module id="session" class="THttpSession" CookieMode="Allow" UseCustomStorage="false"
+ AutoStart="true" GCProbability="1" UseTransparentSessionID="true" TimeOut="3600" />
+ </modules>
+ <pages Theme="PradoSoft" MasterClass="System.Wsat.pages.layout.TWsatLayout" />
+</configuration> \ No newline at end of file
diff --git a/framework/Wsat/pages/layout/TWsatLayout.php b/framework/Wsat/pages/layout/TWsatLayout.php
new file mode 100644
index 00000000..67caa77d
--- /dev/null
+++ b/framework/Wsat/pages/layout/TWsatLayout.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * Description of MainLayout
+ *
+ * @author daniels
+ */
+class TWsatLayout extends TTemplateControl
+{
+
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ $this->validateSecurity();
+ }
+
+ private function validateSecurity()
+ {
+ if ($this->Session["wsat_password"] !== $this->getService()->getPassword())
+ {
+ if (!$this->getPage() instanceof TWsatLogin)
+ {
+ $url = $this->Service->constructUrl('TWsatLogin');
+ $this->Response->redirect($url);
+ }
+ }
+ }
+
+ public function logout()
+ {
+ $this->Session["wsat_password"] = "";
+ $url = $this->Service->constructUrl('TWsatLogin');
+ $this->Response->redirect($url);
+ }
+
+} \ No newline at end of file
diff --git a/framework/Wsat/themes/PradoSoft/main.css b/framework/Wsat/themes/PradoSoft/main.css
new file mode 100644
index 00000000..9970c88b
--- /dev/null
+++ b/framework/Wsat/themes/PradoSoft/main.css
@@ -0,0 +1,152 @@
+html, body{
+ margin: 0px;
+ padding: 0px;
+ font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif;
+ font-weight: normal;
+}
+
+#header {
+ font-size:25px;
+ font-weight:bold;
+ color: #666;
+}
+
+.logo{
+ width: 204px;
+ height:100px;
+ background-image: url('imgs/pradologo.gif');
+ background-repeat: no-repeat;
+ float: left;
+}
+
+.mantisbg{
+ width: 221px;
+ height: 100px;
+ background-image: url('imgs/mantisbg.jpg');
+ background-repeat: no-repeat;
+ float: right;
+}
+
+.mainmenu {
+ padding:10px;
+ padding-right:10px;
+ background:#EDEDED;
+ border-bottom: 1px solid #A6A6A6;
+ border-top: 1px solid #DCDCDC;
+ color:white;
+ text-align:right;
+ font-size: 10pt;
+}
+
+.mainmenu a {
+ color:#737373;
+ text-decoration:none;
+}
+
+.mainmenu a:hover {
+ color: #FF0000;
+}
+
+#toc {
+ background-color: #F3F3F3;
+ width:220px;
+ padding:0px 10px 0px 10px;
+ float: left;
+}
+
+#content {
+ padding: 1em 1em 1em 1em;
+ line-height: 135%;
+ float: left;
+ width: 700px;
+}
+
+.topic {
+ font-size: 9pt;
+ padding: 0px 0px 0px 0px;
+}
+
+.topic div {
+ background-image: url('imgs/arrowdown.gif');
+ background-repeat: no-repeat;
+ background-position: left center;
+ margin: 0px;
+ font-size: 8pt;
+ font-weight:bold;
+ color:#2A480A;
+ padding: 5px;
+ padding-left: 15px;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #E2E2E2;
+}
+
+.topic ul
+{
+ margin: 0px;
+ padding: 0px;
+}
+
+.topic ul li
+{
+ list-style: none;
+ margin: 0px;
+ padding: 5px;
+ padding-left: 15px;
+ border-bottom: 1px dotted #D8D8D8;
+}
+
+.topic a {
+ color:#4F811A;
+ font-size: 8pt;
+ text-decoration: none;
+}
+
+.topic a:hover {
+ color:#2A480A;
+}
+
+/* form styles */
+.form_row{
+ margin: 10px;
+}
+
+.in_text{
+ width: 250px;
+}
+
+.login_form{
+ text-align: center;
+ margin: 30px auto;
+ border: 1px solid red;
+ border-radius: 5px;
+ padding: 10px;
+ width: 250px;
+ font-size: 11px;
+}
+
+.green_panel{
+ background-color: #C5FBBD;
+ border: 1px solid #76C376;
+ padding: 10px;
+ margin: 10px 0;
+ border-radius: 5px;
+ text-align: center;
+}
+
+.red_panel{
+ background-color: #ff6666;
+ border: 1px solid red;
+ padding: 10px;
+ margin: 10px 0;
+ border-radius: 5px;
+ text-align: center;
+}
+
+#footer {
+ clear:both;
+ color: gray;
+ font-size:8pt;
+ text-align:center;
+ margin-top:25px;
+ padding:10px;
+} \ No newline at end of file
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 00000000..94429c9b
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,7 @@
+include.path=${php.global.include.path}
+php.version=PHP_53
+source.encoding=UTF-8
+src.dir=.
+tags.asp=false
+tags.short=true
+web.root=.
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 00000000..f4a5db2d
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.php.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/php-project/1">
+ <name>prado</name>
+ </data>
+ <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1">
+ <word>namespace</word>
+ <word>previosly</word>
+ </spellchecker-wordlist>
+ </configuration>
+</project>