fballiano / p4a Goto Github PK
View Code? Open in Web Editor NEWP4A - PHP For Applications
License: GNU Lesser General Public License v3.0
P4A - PHP For Applications
License: GNU Lesser General Public License v3.0
--------------------------------- -- P4A - PHP For Applications. -- --------------------------------- ------------------ -- Installation -- ------------------ Just extract the archive under your web server DOCUMENT_ROOT (eg: /var/www). You should rename the directory "p4a-version" to "p4a". If you want to test drive a sample application built on P4A open your browser and type: http://localhost/p4a/applications/products_catalogue products_catalogue is an example of a virtual catalogue for shops. To have this application runnning take a look at applications/products_catalogue/README -------------------------- - ADVANCED INSTALLATION -- -------------------------- If you want to have p4a installed out of your document root, this will help you. We use the debian standard way, extract the framework and put it in /usr/share/p4a edit your Apache's httpd.conf and add this lines: Alias /p4a /usr/share/p4a <Directory /usr/share/p4a> Order allow,deny Allow from all </Directory> ------------------- -- Documentation -- ------------------- You'll find P4A code reference under the "docs" folder. All other documentation is available within P4A website: http://p4a.sourceforge.net ------------------------------------ -- P4A compatibility: Server Side -- ------------------------------------ Linux/Windows Apache >= 1.3.0 IIS >= 6.0 php/mod_php >= 5.2.0 ------------------------------------ -- P4A compatibility: Client Side -- ------------------------------------ P4A works with all browsers that supports XHTML and JavaScript. The default theme instead uses CSS2 and some more complex Javascript, so here you have the tested browsers: - Mozilla Firefox 2.x - Internet Explorer 6.x, 7.x - Safari 3.x - Opera 9.25+ (has issues with P4A_DB_Navigator drag&drop) - Google Chrome ----------------------------------------- -- P4A compatibility: Database engines -- ----------------------------------------- P4A works with: - MySQL - PostgreSQL - Oracle - SQLite - Microsoft SQL Server To make P4A connect to a database you need PDO extensions (pdo_mysql, pdo_pgsql, pdo_oci, pdo_sqlite, pdo_mssql). All connections' charsets are set to UTF-8. If you're using Microsoft SQL Server beware that only nchar and nvarchar data type is unicode, thus do not use char and varchar because they're not UTF-8 safe. ------------------ -- KNOWN ISSUES -- ------------------ You can't switch between two application with the same P4A_APPLICATION_NAME under the same virtual host without closing the browser. P4A can't handle database tables with numeric column names. If you want to add calculated fields coming from a DB query (such as DISTICT(example_field)) always use parenthesis and never use the "DISTINCT example_field" syntax. When creating a complex P4A_DB_Source, do not set an alias on the primary key. Oracle's "date" data field is not supported, you should use a char(10). Within your application simply add: $p4a_field->setType("date"); $p4a_field->data_field->setType("date"); If you set P4A_Table's width to 100% and anchor it in a frame/fieldset this won't work cause all frame's cells are floating. ------------- -- Authors -- ------------- Fabrizio Balliano <[email protected]> Andrea Giardina <[email protected]>
With php 5.4.4-14 I got the notice "Non-Static method Net_UserAgent_Detect::detect() should not be called ..." when starting an p4a application. I could remove this message with changing the line 105 in p4a / p4a / libraries / pear_net_useragent_detect.php to
public static function detect($in_userAgent = null, $in_detect = null)
So I would suggest add static to the function "detect".
Latest commit P4A 3.8.5 cause calendar (...) datepicker doesn't popup. Tested using chrome and firefox.
Regarding https://sourceforge.net/projects/p4a/forums/forum/340765/topic/5905682
This could do with being fixed for three reasons:
1 - The custom widget may have it's own P4A ID attribute but if we can't reference that in javascript attached to the application's mask. If there's two widgets, they need different IDs and we can easily handle that if the javascript was in the getAsString() of the custom widget
2 - We can set up variables and constants as part of the widget object but we can't get at those from javascript written as part of the parent mask.
3 - To include the custom widget in your application, you need more configuration to set it up, you can't just drop the widget into your application directory, reference it in a build() function and then expect it to work straight away. You have to copy the widget and then insert the javascript manually. It's sort of OK if you wrote the widget yourself, know how it works and what's needed. It's not OK if you want to release the widget for others to download and use - there's lots of special instructions needed and maybe more support questions...
I'm happy to help debug this issue.
This issue is more a feature request than an issue. Would be useful integrating the Dependency Injection design pattern for P4A 4.x development?
Would be great for lazy building of objects and referring directly to the object and not calling it as a string. Would be also useful for object's configuration management.
hello,
I need to add a jquery plugin for a specific mask in my app, how can i do that?
I try this first:
class MyApp extends P4A {
public function __construct(){
parent::__construct();
$this->addJavascript(P4A_APPLICATION_PATH. "assets/jquery.plugin.js");
}
......
}
Not working
So I try in my mask:
class MyMask extends P4A_Base_Mask{
public function __construct() {
parent::__construct();
$p4a = p4a::singleton();
$p4a->addJavascript(P4A_APPLICATION_PATH. "assets/jquery.plugin.js");
}
}
Thanks 👍
If a field is a reference to another table, the default parameters for this field should be a selection. This way for example these lines would not be needed any more in the mask code
$this->fields->subtable_id
->setLabel("Please select")
->setType("select")
->setSource(P4A::singleton()->subtable)
->setSourceDescriptionField("description");
For the default description field probably the best is to use the first non key field in the subtable. Additional the default setting should be to include a NULL key with the description "not set".
Did P4A was born with accessibility in mind? How much accessible default template should be? Do you think Ajax should be disabled to be totally accessible?
I'm measuring my application's accessibility using http://validatore.it but I got back a few errors (25), I feel I can work on it, maybe I'll post some pull requests in the future.
To use the calendar popup also for fields with type 'timestamp', please add this line in "p4a/p4a/objects/data_sources/db_source.php" at 629:
case 'timestamp':
So the lines should look like:
case 'time':
$this->fields->$name->setType('time');
break;
case 'timestamp':
case 'datetime':
$this->fields->$name->setType('datetime');
break;
case 'number':
if (strlen($meta['SCALE']) == 0) $meta['SCALE'] = 0;
Thanks
Fabrizio I made a small modification to dafault mask, look :
https://github.com/dcarreroc/p4a-status-bar
Greetings
If for a database field a comment is defined this should be used as the default for the field tooltip.
Hi,
I have propably posted on the wrong forum. Please see here: http://sourceforge.net/p/p4a/discussion/340766/thread/a0d684a2/
Would be interesting having Composer PHP as installer and 3rd parties libraries management? Using it, you could manage lazy autoloading of classes during development.
The point would be lifting the developer from instancing of object and concentrate him only on objects configuration and business logic.
I feel P4A extremely RAD and fast also not being well MVC but I felt losing time taking care of object creation. (Also IDE integration isn't well coupled, i mean PHPStorm 7.1)
One of my Masks is now a big object defined by a file >600 lines because of UI and action methods.
Could you suggest any working example for slicing the big mask object in different chunks?
In my case there is a page with three tabs, I'd like to manage three different files, one for each tab.
I would declare click methods in a different file. To do so, should I use namespaces and use?
Another question is: how to load third parties, such as Zend Framework libraries, inside the mask object?
When building a complex query with multiple addJoin(), setFields(), addOrder() etc. it can be difficult see what the actual query looks like when it's sent off to the database.
In ./p4a/objects/data_sources/db_source.php, I've added:
public function inspectQuery() {
return $this->_composeSelectQuery();
}
Which lets me see the SQL while debugging. I'd like to suggest it's added to the base code.
What can you say about triggering AJAX events on P4A? (like table reloading, data editing, select filling)
Manual page is still missing: https://github.com/fballiano/p4a/wiki/How-P4A-manages-AJAX
https://sourceforge.net/projects/p4a/forums/forum/340766/topic/3350745
This would be really handy
The request is to add an audit trial to p4a applications. To log which user has changed which data and when. I suggest the save this information in a table like this
CREATE TABLE IF NOT EXISTS log_data
(
table_name
varchar(200) NOT NULL,
row_id
int(11) NOT NULL,
field_name
varchar(200) DEFAULT NULL,
log_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
user_id
int(11) NOT NULL,
old_value
text,
new_value
text NOT NULL
)
This way the changes of each record can be shown on the masks. Displaying this information based on the standard SQL logging would take much more time I guess.
Would be nice if this could be a feature linked to p4a.
It looks to me that this can be done by adding this code at /p4a/objects/data_sources/db_source.php at function saveRow
if (is_string($pks)) {
$pk_value = $this->fields->$pks->getNewValue();
while($field = $this->fields->nextItem()) {
if ($field->getSchema() != $schema) continue;
if ($field->getTable() != $table) continue;
if ($field->getAliasOf()) {
$name = $field->getAliasOf();
} else {
$name = $field->getName();
}
if (isset($this->_tables_metadata[$table]['metadata'][$name]) and
!$field->isReadOnly() and
!array_key_exists($name, $this->_multivalue_fields)) {
$logNewValue = $field->getNewValue();
$logValue = $field->getValue();
if ($logNewValue <> $logValue) {
if( isset( $_SESSION['log_user'] ) ) {
$log_user = $_SESSION['log_user'];
} else {
$log_user = 0;
}
$db->adapter->query(" INSERT INTO log_data "
. " (table_name, "
. " row_id, "
. " field_name, "
. " user_name, "
. " old_value, "
. " new_value) "
. " VALUES (?, ?, ?, ?, ?, ?)",
array($table,
$pk_value,
$name,
$log_user,
$logValue,
$logNewValue));
}
}
}
}
and at "deleteRow" add
if (isset($this->_tables_metadata[$table]['metadata'][$name]) and
!$field->isReadOnly() and
!array_key_exists($name, $this->_multivalue_fields)) {
if( isset( $_SESSION['log_user'] ) ) {
$log_user = $_SESSION['log_user'];
} else {
$log_user = 0;
}
$logValue = $field->getValue();
$db->adapter->query("INSERT INTO log_data(table_name, row_id, field_name, user_name, old_value, new_value) VALUES(?, ?, ?, ?, ?, 'deleted')", array($table, $pk_value, $name, $log_user, $logValue));
This implies that after the login the session var must be set. So each app using it must have the code line
$_SESSION['log_user'] = $username;
after the successful login.
Hi,
I'm using the multivalue fields to "configure" the same owner mask. So after calling the method saveRow(), the values of every mutlivalue field stills the original.
I've made a change to the db_source.php's code to resolve this issue. I guess is not the best solution, but works for me:
diff --git "a/C:\\Users\\Eddie\\AppData\\Local\\Temp\\TortoiseGit\\db_4C94.tmp\\db_source-703b206-left.php" "b/W:\\wa\\p4a-3.8.5\\p4a\\objects\\data_sources\\db_source.php"
index 1c03b40..b7fdf85 100644
--- "a/C:\\Users\\Eddie\\AppData\\Local\\Temp\\TortoiseGit\\db_4C94.tmp\\db_source-703b206-left.php"
+++ "b/W:\\wa\\p4a-3.8.5\\p4a\\objects\\data_sources\\db_source.php"
@@ -967,6 +967,9 @@ class P4A_DB_Source extends P4A_Data_Source
foreach($row as $field=>$value){
$this->fields->$field->setValue($value);
}
+ foreach ($this->_multivalue_fields as $fieldname=>$aField) {
+ $this->fields->$fieldname->setValue($this->fields->$fieldname->getNewValue());
+ }
$this->updateRowPosition();
} else {
$this->firstRow();
I hope this helps to anyone.
Cheers..!
Eddie Rodríguez
Add a copy "copy record" button to the toolbar that:
This way users can save much time, when they have to enter several simular records
Hello Fabrizio
I just upload my contribs to github
Greetings
The "tablename_seq_id is not correct after a non p4a has inserted a record into a table of a MySQL database.
P4A creates a table with [tablename]_[PK_name]seq. After inserting a new record in [tablename] using a normal SQL statement and not using P4A the id in [tablename][PK_name]seq is not increased. If after that P4A tries to create a new record an SQL error appears. This problem can be solved manually by setting the AUTO_INCREMENT in the original table AND in the [tablename][PK_name]_seq table.
But I guess P4A should handle cases like this automatically. Maybe this can be done by modifying nextSequenceId in p4a_db.php so get's the real last ID of the table instead of using lastInsertId() in the exception handling. Maybe this can be solved also in the zend framwork.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.