From ee3998f62ed25ce07fe5cbc9bb98f69fbb025320 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 22 Nov 2017 12:08:54 +0100 Subject: [PATCH 01/10] - Changed system/dbupdate_3.3.php to create table system.tbl_filters and what its needed - Added model system/Filters_model to manage system.tbl_filters - Removed method execQuery from model system/UDF_model - Added property executedQueryMetaData to DB_Model - Added property executedQueryListFields to DB_Model - Added method getExecutedQueryListFields to DB_Model - Added method getExecutedQueryMetaData to DB_Model - Added method execReadOnlyQuery to DB_Model to execute read only queries from outside a model - Changed DB_Model method _toPhp to store infos about an executed query into properties executedQueryMetaData and executedQueryListFields - Updated library UDFLib to use execReadOnlyQuery - Added widget FilterWidget to render and manage a filter into VileSci - Added views widgets/filter/selectFields, widgets/filter/selectFilters and widgets/filter/tableDataset used by FilterWidget --- application/controllers/system/Test.php | 38 +++ application/core/DB_Model.php | 58 ++++- application/libraries/UDFLib.php | 2 +- application/models/system/Filters_model.php | 14 ++ application/models/system/UDF_model.php | 95 +++----- .../views/widgets/filter/selectFields.php | 20 ++ .../views/widgets/filter/selectFilters.php | 20 ++ .../views/widgets/filter/tableDataset.php | 9 + application/widgets/FilterWidget.php | 61 +++++ system/dbupdate_3.3.php | 220 ++++++++++++++++++ 10 files changed, 468 insertions(+), 69 deletions(-) create mode 100644 application/controllers/system/Test.php create mode 100644 application/models/system/Filters_model.php create mode 100644 application/views/widgets/filter/selectFields.php create mode 100644 application/views/widgets/filter/selectFilters.php create mode 100644 application/views/widgets/filter/tableDataset.php create mode 100644 application/widgets/FilterWidget.php diff --git a/application/controllers/system/Test.php b/application/controllers/system/Test.php new file mode 100644 index 000000000..f22898a34 --- /dev/null +++ b/application/controllers/system/Test.php @@ -0,0 +1,38 @@ +load->library('WidgetLib'); + } + + /** + * + */ + public function index() + { + echo $this->widgetlib->widget( + 'FilterWidget', + array( + 'app' => 'OpenProject', + 'datasetName' => 'Arbeitspakete', + 'query' => ' + SELECT p.person_id AS PersonId, + p.nachname AS Nachname, + p.vorname AS Vorname, + k.kontakt AS Email + FROM public.tbl_person p INNER JOIN public.tbl_kontakt k USING(person_id) + WHERE p.aktiv = TRUE + AND p.person_id = k.person_id + AND k.kontakttyp = \'email\' + AND p.person_id < 1000 + ' + ) + ); + } +} diff --git a/application/core/DB_Model.php b/application/core/DB_Model.php index ab5ab2768..e6bd31114 100644 --- a/application/core/DB_Model.php +++ b/application/core/DB_Model.php @@ -23,6 +23,9 @@ class DB_Model extends FHC_Model protected $hasSequence; // False if this table has a composite primary key that is not using a sequence // True if this table has a primary key that uses a sequence + private $executedQueryMetaData; + private $executedQueryListFields; + /** * Constructor */ @@ -670,6 +673,44 @@ class DB_Model extends FHC_Model return $this->fieldExists(UDFLib::COLUMN_NAME); } + /** + * Get the list of the fields after having executed a query + */ + public function getExecutedQueryListFields() + { + return $this->executedQueryListFields; + } + + /** + * Get meda data info about the retrived fields after having executed a query + */ + public function getExecutedQueryMetaData() + { + return $this->executedQueryMetaData; + } + + /** + * Like execQuery, but it allows only to perform queries to read data + */ + public function execReadOnlyQuery($query, $parametersArray = null) + { + // + if (!stripos($query, 'INSERT') + && !stripos($query, 'UPDATE') + && !stripos($query, 'DELETE') + && !stripos($query, 'CREATE') + && !stripos($query, 'ALTER') + && !stripos($query, 'GRANT') + && !stripos($query, 'DROP')) + { + return $this->execQuery($query, $parametersArray); + } + else + { + return error('You are allowed to run only query for reading data'); + } + } + // ------------------------------------------------------------------------------------------ // Protected methods @@ -809,20 +850,23 @@ class DB_Model extends FHC_Model if (is_object($result)) { $toBeConverterdArray = array(); // Fields to be converted - $metaDataArray = $result->field_data(); // Fields information - for ($i = 0; $i < count($metaDataArray); $i++) // Looking for booleans and arrays + + $this->executedQueryMetaData = $result->field_data(); // Fields information + $this->executedQueryListFields = $result->list_fields(); // List of the retrived fields + + for ($i = 0; $i < count($this->executedQueryMetaData); $i++) // Looking for booleans and arrays { // If array type, boolean type OR a UDF - if (strpos($metaDataArray[$i]->type, DB_Model::PGSQL_ARRAY_TYPE) !== false - || $metaDataArray[$i]->type == DB_Model::PGSQL_BOOLEAN_TYPE - || $this->udflib->isUDFColumn($metaDataArray[$i]->name, $metaDataArray[$i]->type)) + if (strpos($this->executedQueryMetaData[$i]->type, DB_Model::PGSQL_ARRAY_TYPE) !== false + || $this->executedQueryMetaData[$i]->type == DB_Model::PGSQL_BOOLEAN_TYPE + || $this->udflib->isUDFColumn($this->executedQueryMetaData[$i]->name, $this->executedQueryMetaData[$i]->type)) { // Name and type of the field to be converted $toBeConverted = new stdClass(); // Set the type of the field to be converted - $toBeConverted->type = $metaDataArray[$i]->type; + $toBeConverted->type = $this->executedQueryMetaData[$i]->type; // Set the name of the field to be converted - $toBeConverted->name = $metaDataArray[$i]->name; + $toBeConverted->name = $this->executedQueryMetaData[$i]->name; // Add the field to be converted to $toBeConverterdArray array_push($toBeConverterdArray, $toBeConverted); } diff --git a/application/libraries/UDFLib.php b/application/libraries/UDFLib.php index 1e16c11ac..2d453f068 100644 --- a/application/libraries/UDFLib.php +++ b/application/libraries/UDFLib.php @@ -625,7 +625,7 @@ class UDFLib elseif (isset($jsonSchema->{UDFLib::LIST_VALUES}->sql)) { // UDFModel is loaded in method _loadUDF that is called before the current method - $queryResult = $this->_ci->UDFModel->execQuery($jsonSchema->{UDFLib::LIST_VALUES}->sql); + $queryResult = $this->_ci->UDFModel->execReadOnlyQuery($jsonSchema->{UDFLib::LIST_VALUES}->sql); if (hasData($queryResult)) { $parameters = $queryResult->retval; diff --git a/application/models/system/Filters_model.php b/application/models/system/Filters_model.php new file mode 100644 index 000000000..546e2a5fd --- /dev/null +++ b/application/models/system/Filters_model.php @@ -0,0 +1,14 @@ +dbTable = 'system.tbl_filters'; + $this->pk = 'filter_id'; + } +} diff --git a/application/models/system/UDF_model.php b/application/models/system/UDF_model.php index e9bef54f6..ae9a91a69 100644 --- a/application/models/system/UDF_model.php +++ b/application/models/system/UDF_model.php @@ -6,10 +6,10 @@ class UDF_model extends DB_Model const STRING_NULL = 'null'; const STRING_TRUE = 'true'; const STRING_FALSE = 'false'; - + const UDF_DROPDOWN_TYPE = 'dropdown'; const UDF_MULTIPLEDROPDOWN_TYPE = 'multipledropdown'; - + /** * Constructor */ @@ -20,41 +20,14 @@ class UDF_model extends DB_Model $this->pk = array('schema', 'table'); $this->hasSequence = false; } - - /** - * Override DB_Model method execQuery to allow only to perform queries to read data - */ - public function execQuery($query, $parametersArray = null) - { - // - if ( - ( - substr($query, 0, 6) == 'SELECT' - || substr($query, 0, 4) == 'WITH' - ) - && - ( - !stripos($query, 'INSERT') - && !stripos($query, 'UPDATE') - && !stripos($query, 'DELETE') - ) - ) - { - return parent::execQuery($query, $parametersArray); - } - else - { - return error('You are allowed to run only query for reading data'); - } - } - + /** * Returns all the UDF for this table */ public function getUDFsDefinitions($schemaAndTable) { $st = $this->getSchemaAndTable($schemaAndTable); - + $this->addSelect(UDFLib::COLUMN_JSON_DESCRIPTION); $udfResults = $this->loadWhere( array( @@ -62,13 +35,13 @@ class UDF_model extends DB_Model 'table' => $st->table ) ); - + return $udfResults; } // ------------------------------------------------------------------------------------ // These methods work only with the this version of FAS, not with the future versions - + /** * Methods to save data from FAS */ @@ -77,53 +50,53 @@ class UDF_model extends DB_Model $result = error('No way man!'); $resultPerson = success('person'); $resultPrestudent = success('prestudent'); - + $person_id = $udfs['person_id']; unset($udfs['person_id']); - + $prestudent_id = $udfs['prestudent_id']; unset($udfs['prestudent_id']); - + $jsons = array(); - - // + + // if (isset($person_id)) { // Load model Person_model $this->load->model('person/Person_model', 'PersonModel'); - + $result = $this->load(array('public', 'tbl_person')); if (isSuccess($result) && count($result->retval) == 1) { $jsons = json_decode($result->retval[0]->jsons); } - + $udfs = $this->_fillMissingTextUDF($udfs, $jsons); $udfs = $this->_fillMissingChkboxUDF($udfs, $jsons); $udfs = $this->_fillMissingDropdownUDF($udfs, $jsons); - + $resultPerson = $this->PersonModel->update($person_id, $udfs); } - - // + + // if (isset($prestudent_id)) { // Load model Prestudent_model $this->load->model('crm/Prestudent_model', 'PrestudentModel'); - + $result = $this->load(array('public', 'tbl_prestudent')); if (isSuccess($result) && count($result->retval) == 1) { $jsons = json_decode($result->retval[0]->jsons); } - + $udfs = $this->_fillMissingTextUDF($udfs, $jsons); $udfs = $this->_fillMissingChkboxUDF($udfs, $jsons); $udfs = $this->_fillMissingDropdownUDF($udfs, $jsons); - + $resultPrestudent = $this->PrestudentModel->update($prestudent_id, $udfs); } - + if (isSuccess($resultPerson) && isSuccess($resultPrestudent)) { $result = success(array($resultPerson->retval, $resultPrestudent->retval)); @@ -136,17 +109,17 @@ class UDF_model extends DB_Model { $result = $resultPrestudent; } - + return $result; } - + /** - * + * */ private function _fillMissingChkboxUDF($udfs, $jsons) { $_fillMissingChkboxUDF = $udfs; - + foreach($jsons as $udfDescription) { if ($udfDescription->{UDFLib::TYPE} == UDFLib::CHKBOX_TYPE) @@ -168,17 +141,17 @@ class UDF_model extends DB_Model } } } - + return $_fillMissingChkboxUDF; } - + /** - * + * */ private function _fillMissingDropdownUDF($udfs, $jsons) { $_fillMissingDropdownUDF = $udfs; - + foreach($jsons as $udfDescription) { if ($udfDescription->{UDFLib::TYPE} == UDF_model::UDF_DROPDOWN_TYPE @@ -194,17 +167,17 @@ class UDF_model extends DB_Model } } } - + return $_fillMissingDropdownUDF; } - + /** - * + * */ private function _fillMissingTextUDF($udfs, $jsons) { $_fillMissingTextUDF = $udfs; - + foreach($jsons as $udfDescription) { if ($udfDescription->{UDFLib::TYPE} == 'textarea' @@ -220,7 +193,7 @@ class UDF_model extends DB_Model } } } - + return $_fillMissingTextUDF; } -} \ No newline at end of file +} diff --git a/application/views/widgets/filter/selectFields.php b/application/views/widgets/filter/selectFields.php new file mode 100644 index 000000000..a4f11dbfb --- /dev/null +++ b/application/views/widgets/filter/selectFields.php @@ -0,0 +1,20 @@ +
+ $value) + { + echo ''; + } + ?> +
+
+ Add: + +
diff --git a/application/views/widgets/filter/selectFilters.php b/application/views/widgets/filter/selectFilters.php new file mode 100644 index 000000000..72f963b57 --- /dev/null +++ b/application/views/widgets/filter/selectFilters.php @@ -0,0 +1,20 @@ +
+ $value) + { + echo $value->name.' - '.$value->type.'
'; + } + ?> +
+
+ Add filter: + +
diff --git a/application/views/widgets/filter/tableDataset.php b/application/views/widgets/filter/tableDataset.php new file mode 100644 index 000000000..6927a0923 --- /dev/null +++ b/application/views/widgets/filter/tableDataset.php @@ -0,0 +1,9 @@ +
+ retval; + foreach ($result as $key => $value) + { + var_dump($value); + } + ?> +
diff --git a/application/widgets/FilterWidget.php b/application/widgets/FilterWidget.php new file mode 100644 index 000000000..721fd7c55 --- /dev/null +++ b/application/widgets/FilterWidget.php @@ -0,0 +1,61 @@ +load->model('system/Filters_model', 'FiltersModel'); + + $this->app = $widgetData['app']; + $this->datasetName = $widgetData['datasetName']; + + $dataset = $this->FiltersModel->execReadOnlyQuery($widgetData['query']); + + $this->loadViewSelectFields($this->FiltersModel->getExecutedQueryListFields()); + + $this->loadViewSelectFilters($this->FiltersModel->getExecutedQueryMetaData()); + + $this->loadViewTableDataset($dataset); + } + + /** + * + */ + private function loadViewSelectFields($listFields) + { + $this->view('widgets/filter/selectFields', array('listFields' => $listFields)); + } + + /** + * + */ + private function loadViewSelectFilters($metaData) + { + $this->view('widgets/filter/selectFilters', array('metaData' => $metaData)); + } + + /** + * + */ + private function loadViewTableDataset($result) + { + $this->view('widgets/filter/tableDataset', array('dataset' => $result)); + } +} diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 55b272bab..771a3f5e7 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -674,6 +674,225 @@ if ($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berech //--------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- +// Start filters + +// SEQUENCE tbl_filters_id_seq +if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'tbl_filters_id_seq'")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = ' + CREATE SEQUENCE system.tbl_filters_id_seq + START WITH 1 + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + '; + if(!$db->db_query($qry)) + echo 'system.tbl_filters_id_seq '.$db->db_last_error().'
'; + else + echo '
Created sequence: system.tbl_filters_id_seq'; + + // GRANT SELECT, UPDATE ON SEQUENCE system.tbl_filters_id_seq TO vilesci; + $qry = 'GRANT SELECT, UPDATE ON SEQUENCE system.tbl_filters_id_seq TO vilesci;'; + if (!$db->db_query($qry)) + echo 'system.tbl_filters_id_seq '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on system.tbl_filters_id_seq'; + + // GRANT SELECT, UPDATE ON SEQUENCE system.tbl_filters_id_seq TO fhcomplete; + $qry = 'GRANT SELECT, UPDATE ON SEQUENCE system.tbl_filters_id_seq TO fhcomplete;'; + if (!$db->db_query($qry)) + echo 'system.tbl_filters_id_seq '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on system.tbl_filters_id_seq'; + } +} + +// TABLE system.tbl_filters +if (!@$db->db_query("SELECT 0 FROM system.tbl_filters WHERE 0 = 1")) +{ + $qry = ' + CREATE TABLE system.tbl_filters ( + filter_id integer NOT NULL DEFAULT nextval(\'system.tbl_filters_id_seq\'::regclass), + app character varying(32) NOT NULL, + dataset_name character varying(128) NOT NULL, + filter_kurzbz character varying(64) NOT NULL, + person_id integer, + description character varying(128)[] NOT NULL, + sort integer, + default_filter boolean DEFAULT FALSE, + filter jsonb NOT NULL, + oe_kurzbz character varying(16) + );'; + if (!$db->db_query($qry)) + echo 'system.tbl_filters '.$db->db_last_error().'
'; + else + echo '
Created table system.tbl_filters'; + + // GRANT SELECT ON TABLE system.tbl_filters TO web; + $qry = 'GRANT SELECT ON TABLE system.tbl_filters TO web;'; + if (!$db->db_query($qry)) + echo 'system.tbl_filters '.$db->db_last_error().'
'; + else + echo '
Granted privileges to web on system.tbl_filters'; + + // GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE system.tbl_filters TO vilesci; + $qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE system.tbl_filters TO vilesci;'; + if (!$db->db_query($qry)) + echo 'system.tbl_filters '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on system.tbl_filters'; + + // COMMENT ON TABLE system.tbl_filters + $qry = 'COMMENT ON TABLE system.tbl_filters IS \'Table to manage filters\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters'; + + // COMMENT ON TABLE system.tbl_filters.app + $qry = 'COMMENT ON COLUMN system.tbl_filters.app IS \'Application which this filter belongs to\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.app: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.app'; + + // COMMENT ON TABLE system.tbl_filters.dataset_name + $qry = 'COMMENT ON COLUMN system.tbl_filters.dataset_name IS \'Name that identifies the data set to be filtered\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.dataset_name: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.dataset_name'; + + // COMMENT ON TABLE system.tbl_filters.filter_kurzbz + $qry = 'COMMENT ON COLUMN system.tbl_filters.filter_kurzbz IS \'Short description of the filter, unique for this application and this data set\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.filter_kurzbz: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.filter_kurzbz'; + + // COMMENT ON TABLE system.tbl_filters.person_id + $qry = 'COMMENT ON COLUMN system.tbl_filters.person_id IS \'Person identifier which this filter belongs to. If null it is global\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.person_id: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.person_id'; + + // COMMENT ON TABLE system.tbl_filters.description + $qry = 'COMMENT ON COLUMN system.tbl_filters.description IS \'Long description for this filter\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.description: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.description'; + + // COMMENT ON TABLE system.tbl_filters.sort + $qry = 'COMMENT ON COLUMN system.tbl_filters.sort IS \'Indicates the order in which the filters appear in a list\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.sort: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.sort'; + + // COMMENT ON TABLE system.tbl_filters.default_filter + $qry = 'COMMENT ON COLUMN system.tbl_filters.default_filter IS \'If it is the default filter for that data set\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.default_filter: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.default_filter'; + + // COMMENT ON TABLE system.tbl_filters.filter + $qry = 'COMMENT ON COLUMN system.tbl_filters.filter IS \'Cointains json that define the filter\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.filter: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.filter'; + + // COMMENT ON TABLE system.tbl_filters.oe_kurzbz + $qry = 'COMMENT ON COLUMN system.tbl_filters.oe_kurzbz IS \'Organisation unit which this filter belongs to. If null it is for all the organisation units\';'; + if (!$db->db_query($qry)) + echo 'Adding comment to system.tbl_filters.oe_kurzbz: '.$db->db_last_error().'
'; + else + echo '
Added comment to system.tbl_filters.oe_kurzbz'; + + // ALTER SEQUENCE system.tbl_filters_id_seq OWNED BY system.tbl_filters.filter_id; + $qry = 'ALTER SEQUENCE system.tbl_filters_id_seq OWNED BY system.tbl_filters.filter_id;'; + if (!$db->db_query($qry)) + echo 'system.tbl_filters_id_seq '.$db->db_last_error().'
'; + else + echo '
Altered sequence system.tbl_filters_id_seq'; +} + +// UNIQUE INDEX uidx_filters_app_dataset_name_filter_kurzbz +if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'uidx_filters_app_dataset_name_filter_kurzbz'")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = 'CREATE UNIQUE INDEX uidx_filters_app_dataset_name_filter_kurzbz ON system.tbl_filters USING btree (app, dataset_name, filter_kurzbz);'; + if (!$db->db_query($qry)) + echo 'uidx_filters_app_dataset_name_filter_kurzbz '.$db->db_last_error().'
'; + else + echo '
Created unique uidx_filters_app_dataset_name_filter_kurzbz'; + } +} + +// Add permission for filters +if ($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'system/filters';")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung (berechtigung_kurzbz, beschreibung) VALUES('system/filters', 'To manage core filters');"; + if (!$db->db_query($qry)) + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + else + echo ' system.tbl_berechtigung: Added permission for filters
'; + } +} + +// FOREIGN KEY tbl_filters_app_fkey +if ($result = $db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'tbl_filters_app_fkey'")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = 'ALTER TABLE system.tbl_filters ADD CONSTRAINT tbl_filters_app_fkey FOREIGN KEY (app) REFERENCES system.tbl_app(app) ON UPDATE CASCADE ON DELETE RESTRICT;'; + if (!$db->db_query($qry)) + echo 'tbl_filters_app_fkey '.$db->db_last_error().'
'; + else + echo '
Created foreign key tbl_filters_app_fkey'; + } +} + +// FOREIGN KEY tbl_filters_person_id_fkey +if ($result = $db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'tbl_filters_person_id_fkey'")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = 'ALTER TABLE system.tbl_filters ADD CONSTRAINT tbl_filters_person_id_fkey FOREIGN KEY (person_id) REFERENCES public.tbl_person(person_id) ON UPDATE CASCADE ON DELETE RESTRICT;'; + if (!$db->db_query($qry)) + echo 'tbl_filters_person_id_fkey '.$db->db_last_error().'
'; + else + echo '
Created foreign key tbl_filters_person_id_fkey'; + } +} + +// FOREIGN KEY tbl_filters_oe_kurzbz_fkey +if ($result = $db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'tbl_filters_oe_kurzbz_fkey'")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = 'ALTER TABLE system.tbl_filters ADD CONSTRAINT tbl_filters_oe_kurzbz_fkey FOREIGN KEY (oe_kurzbz) REFERENCES public.tbl_organisationseinheit(oe_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT;'; + if (!$db->db_query($qry)) + echo 'tbl_filters_oe_kurzbz_fkey '.$db->db_last_error().'
'; + else + echo '
Created foreign key tbl_filters_oe_kurzbz_fkey'; + } +} + +// End filters +//--------------------------------------------------------------------------------------------------------------------- + + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -923,6 +1142,7 @@ $tabellen=array( "system.tbl_benutzerrolle" => array("benutzerberechtigung_id","rolle_kurzbz","berechtigung_kurzbz","uid","funktion_kurzbz","oe_kurzbz","art","studiensemester_kurzbz","start","ende","negativ","updateamum", "updatevon","insertamum","insertvon","kostenstelle_id","anmerkung"), "system.tbl_berechtigung" => array("berechtigung_kurzbz","beschreibung"), "system.tbl_extensions" => array("extension_id","name","version","description","license","url","core_version","dependencies","enabled"), + "system.tbl_filters" => array("filter_id","app","dataset_name","filter_kurzbz","person_id","description","sort","default_filter","filter","oe_kurzbz"), "system.tbl_phrase" => array("phrase_id","app","phrase","insertamum","insertvon"), "system.tbl_phrasentext" => array("phrasentext_id","phrase_id","sprache","orgeinheit_kurzbz","orgform_kurzbz","text","description","insertamum","insertvon"), "system.tbl_rolle" => array("rolle_kurzbz","beschreibung"), From c105363fd034290c0502d3007d17e924f8f899d3 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 22 Nov 2017 15:33:44 +0100 Subject: [PATCH 02/10] First preview completed --- application/controllers/system/Test.php | 9 +-- application/views/widgets/filter/filter.php | 15 +++++ .../views/widgets/filter/selectFilters.php | 41 +++++++++++++- .../views/widgets/filter/tableDataset.php | 55 ++++++++++++++++--- application/widgets/FilterWidget.php | 21 +++++-- 5 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 application/views/widgets/filter/filter.php diff --git a/application/controllers/system/Test.php b/application/controllers/system/Test.php index f22898a34..67e82c7d3 100644 --- a/application/controllers/system/Test.php +++ b/application/controllers/system/Test.php @@ -22,10 +22,11 @@ class Test extends VileSci_Controller 'app' => 'OpenProject', 'datasetName' => 'Arbeitspakete', 'query' => ' - SELECT p.person_id AS PersonId, - p.nachname AS Nachname, - p.vorname AS Vorname, - k.kontakt AS Email + SELECT p.person_id AS "PersonId", + p.nachname AS "Nachname", + p.vorname AS "Vorname", + k.kontakt AS "Email", + p.aktiv AS "Aktiv" FROM public.tbl_person p INNER JOIN public.tbl_kontakt k USING(person_id) WHERE p.aktiv = TRUE AND p.person_id = k.person_id diff --git a/application/views/widgets/filter/filter.php b/application/views/widgets/filter/filter.php new file mode 100644 index 000000000..542708900 --- /dev/null +++ b/application/views/widgets/filter/filter.php @@ -0,0 +1,15 @@ +
+ view('widgets/filter/selectFields', array('listFields' => $listFields)); ?> +
+ +
+ +
+ view('widgets/filter/selectFilters', array('metaData' => $metaData)); ?> +
+ +
+ +
+ view('widgets/filter/tableDataset', array('dataset' => $dataset)); ?> +
diff --git a/application/views/widgets/filter/selectFilters.php b/application/views/widgets/filter/selectFilters.php index 72f963b57..ff3995727 100644 --- a/application/views/widgets/filter/selectFilters.php +++ b/application/views/widgets/filter/selectFilters.php @@ -2,7 +2,46 @@ $value) { - echo $value->name.' - '.$value->type.'
'; + echo '
'; + echo $value->name; + + if ($value->type == 'int4') + { + ?> + + + + + type == 'varchar') + { + ?> + + + + type == 'bool') + { + ?> + + + '; } ?>
diff --git a/application/views/widgets/filter/tableDataset.php b/application/views/widgets/filter/tableDataset.php index 6927a0923..83ca7b95f 100644 --- a/application/views/widgets/filter/tableDataset.php +++ b/application/views/widgets/filter/tableDataset.php @@ -1,9 +1,50 @@ + + + + + + + + + + + +
- retval; - foreach ($result as $key => $value) - { - var_dump($value); - } - ?> + + + + + + + + + + + + retval; + foreach ($result as $key => $value) + { + ?> + + + + + + + + + +
PersonIdNachnameVornameEmailAktiv
PersonId; ?>Nachname; ?>Vorname; ?>Email; ?>Aktiv === true ? 'True' : 'False'; ?>
diff --git a/application/widgets/FilterWidget.php b/application/widgets/FilterWidget.php index 721fd7c55..a7715aa57 100644 --- a/application/widgets/FilterWidget.php +++ b/application/widgets/FilterWidget.php @@ -28,11 +28,22 @@ class FilterWidget extends Widget $dataset = $this->FiltersModel->execReadOnlyQuery($widgetData['query']); - $this->loadViewSelectFields($this->FiltersModel->getExecutedQueryListFields()); + $listFields = $this->FiltersModel->getExecutedQueryListFields(); - $this->loadViewSelectFilters($this->FiltersModel->getExecutedQueryMetaData()); + $metaData = $this->FiltersModel->getExecutedQueryMetaData(); - $this->loadViewTableDataset($dataset); + $this->loadViewFilters($listFields, $metaData, $dataset); + } + + /** + * + */ + private function loadViewFilters($listFields, $metaData, $dataset) + { + $this->view( + 'widgets/filter/filter', + array('listFields' => $listFields, 'metaData' => $metaData, 'dataset' => $dataset) + ); } /** @@ -54,8 +65,8 @@ class FilterWidget extends Widget /** * */ - private function loadViewTableDataset($result) + private function loadViewTableDataset($dataset) { - $this->view('widgets/filter/tableDataset', array('dataset' => $result)); + $this->view('widgets/filter/tableDataset', array('dataset' => $dataset)); } } From 80b954365e6f7ccdd95d9e49188386772cca2a78 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 29 Nov 2017 18:24:54 +0100 Subject: [PATCH 03/10] Bugfix tablesorter, if a table is empty jquery not works anymore --- application/views/templates/header.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/application/views/templates/header.php b/application/views/templates/header.php index e995fb7f3..0cb3a9fad 100644 --- a/application/views/templates/header.php +++ b/application/views/templates/header.php @@ -69,12 +69,17 @@ if($jqueryV1 && $jqueryCurrent) @@ -108,4 +113,5 @@ if($jqueryV1 && $jqueryCurrent) + From 34329edb74dd6d6dcadb848778f5ecb35f793e2c Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 29 Nov 2017 18:26:43 +0100 Subject: [PATCH 04/10] - Better code style - Clened views structure - Use session to store the filter state --- application/views/widgets/filter/filter.php | 58 ++- .../views/widgets/filter/selectFields.php | 9 +- .../views/widgets/filter/selectFilters.php | 90 ++-- .../views/widgets/filter/tableDataset.php | 59 ++- application/widgets/FilterWidget.php | 452 +++++++++++++++++- 5 files changed, 556 insertions(+), 112 deletions(-) diff --git a/application/views/widgets/filter/filter.php b/application/views/widgets/filter/filter.php index 542708900..2be9bd405 100644 --- a/application/views/widgets/filter/filter.php +++ b/application/views/widgets/filter/filter.php @@ -1,15 +1,51 @@ -
- view('widgets/filter/selectFields', array('listFields' => $listFields)); ?> -
+load->view( + 'templates/header', + array('title' => 'Filters', 'tablesort' => true, 'tableid' => 'tableDataset', 'widgets' => 'zebra') + ); +?> + + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +load->view('templates/footer'); +?> diff --git a/application/views/widgets/filter/selectFields.php b/application/views/widgets/filter/selectFields.php index a4f11dbfb..5129b9829 100644 --- a/application/views/widgets/filter/selectFields.php +++ b/application/views/widgets/filter/selectFields.php @@ -1,14 +1,17 @@
$value) + $selectedFields = FilterWidget::getSelectedFields(); + + foreach ($selectedFields as $key => $value) { - echo ''; + echo ''; } ?> +
Add: - $value) diff --git a/application/views/widgets/filter/selectFilters.php b/application/views/widgets/filter/selectFilters.php index ff3995727..bea5d7f00 100644 --- a/application/views/widgets/filter/selectFilters.php +++ b/application/views/widgets/filter/selectFilters.php @@ -1,59 +1,47 @@
+ +
+ + + name; ?> + + + + + + + + +
+ + +
+
+ + Add filter: + + + - - - - - - - - + type == 'varchar') - { - ?> - - - - type == 'bool') - { - ?> - - - '; } ?> -
-
- Add filter: - + +
diff --git a/application/views/widgets/filter/tableDataset.php b/application/views/widgets/filter/tableDataset.php index 83ca7b95f..402041ff8 100644 --- a/application/views/widgets/filter/tableDataset.php +++ b/application/views/widgets/filter/tableDataset.php @@ -1,48 +1,43 @@ - +retval; - - - - - - - - - + $selectedFields = FilterWidget::getSelectedFields(); +?>
- +
- - - - - + $value) + { + if (array_key_exists($value, $result[0])) + { + ?> + + retval; foreach ($result as $key => $value) { + echo ""; + + foreach ($selectedFields as $key2 => $value2) + { + if (array_key_exists($value2, $value)) + { ?> - - - - - - - + "; } ?> diff --git a/application/widgets/FilterWidget.php b/application/widgets/FilterWidget.php index a7715aa57..bf8efbf27 100644 --- a/application/widgets/FilterWidget.php +++ b/application/widgets/FilterWidget.php @@ -5,7 +5,33 @@ */ class FilterWidget extends Widget { + const APP_PARAMETER = 'app'; + const QUERY_PARAMETER = 'query'; + const DATASET_NAME_PARAMETER = 'datasetName'; + + const DATASET_PARAMETER = 'dataset'; + const METADATA_PARAMETER = 'metaData'; + const LIST_FIELDS_PARAMETER = 'listFields'; + + const WIDGET_URL_FILTER = 'widgets/filter/filter'; + const WIDGET_URL_SELECT_FIELDS = 'widgets/filter/selectFields'; + const WIDGET_URL_TABLE_DATASET = 'widgets/filter/tableDataset'; + const WIDGET_URL_SELECT_FILTERS = 'widgets/filter/selectFilters'; + + const SESSION_NAME = 'FILTER'; + + const SELECTED_FIELDS = 'selectedFields'; + const SELECTED_FILTERS = 'selectedFilters'; + const ACTIVE_FILTERS = 'activeFilters'; + + const CMD_ADD_FILTER = 'addFilter'; + const CMD_REMOVE_FILTER = 'rmFilter'; + const CMD_ADD_FIELD = 'addField'; + const CMD_REMOVE_FIELD = 'rmField'; + const CMD_APPLY_FILTERS = 'applyFilters'; + private $app; + private $query; private $datasetName; /** @@ -13,7 +39,14 @@ class FilterWidget extends Widget */ public function __construct($name, $args = array()) { - parent::__construct($name, $args); + parent::__construct($name, $args); // + + $this->_initFilterWidget($args); // + + $this->_initSession(); // + + // + $this->load->model('system/Filters_model', 'FiltersModel'); } /** @@ -21,52 +54,441 @@ class FilterWidget extends Widget */ public function display($widgetData) { - $this->load->model('system/Filters_model', 'FiltersModel'); + // + $this->_setSessionFilterData(); - $this->app = $widgetData['app']; - $this->datasetName = $widgetData['datasetName']; - - $dataset = $this->FiltersModel->execReadOnlyQuery($widgetData['query']); + // + $dataset = $this->FiltersModel->execReadOnlyQuery($this->_generateQuery()); + // $listFields = $this->FiltersModel->getExecutedQueryListFields(); + // $metaData = $this->FiltersModel->getExecutedQueryMetaData(); + // $this->loadViewFilters($listFields, $metaData, $dataset); } /** * */ - private function loadViewFilters($listFields, $metaData, $dataset) + public static function getSelectedFields() { + return self::_getFromSession(self::SELECTED_FIELDS); + } + + /** + * + */ + public static function getSelectedFilters() + { + return self::_getFromSession(self::SELECTED_FILTERS); + } + + /** + * + */ + public static function loadViewTableDataset($dataset) + { + self::_loadView(self::WIDGET_URL_TABLE_DATASET, array(self::DATASET_PARAMETER => $dataset)); + } + + /** + * + */ + public static function loadViewSelectFilters($metaData) + { + self::_loadView(self::WIDGET_URL_SELECT_FILTERS, array(self::METADATA_PARAMETER => $metaData)); + } + + /** + * + */ + public static function loadViewSelectFields($listFields) + { + self::_loadView(self::WIDGET_URL_SELECT_FIELDS, array(self::LIST_FIELDS_PARAMETER => $listFields)); + } + + /** + * + */ + public static function getFilterMetaData($filter, $metaData) + { + $md = null; + + for ($metaDataCounter = 0; $metaDataCounter < count($metaData); $metaDataCounter++) + { + if ($metaData[$metaDataCounter]->name == $filter) + { + $md = $metaData[$metaDataCounter]; + break; + } + } + + return $md; + } + + /** + * + */ + public static function renderFilterType($filterMetaData) + { + $html = ''; + $value = self::_getActiveFilterValue($filterMetaData->name); + + if ($filterMetaData->type == 'int4') + { + $html = ' + + + + + + + '; + } + elseif ($filterMetaData->type == 'varchar') + { + $html = ' + + + + + + + '; + } + elseif ($filterMetaData->type == 'bool') + { + $html = ' + + + + + + + '; + } + + return sprintf($html, $filterMetaData->name.'-operation', $filterMetaData->name, $value); + } + + /** + * + */ + protected function loadViewFilters($listFields, $metaData, $dataset) + { + // Loads views $this->view( - 'widgets/filter/filter', - array('listFields' => $listFields, 'metaData' => $metaData, 'dataset' => $dataset) + self::WIDGET_URL_FILTER, + array( + self::DATASET_PARAMETER => $dataset, + self::METADATA_PARAMETER => $metaData, + self::LIST_FIELDS_PARAMETER => $listFields + ) ); } /** * */ - private function loadViewSelectFields($listFields) + private static function _getFromSession($key) { - $this->view('widgets/filter/selectFields', array('listFields' => $listFields)); + $_getFromSession = null; + $ci =& get_instance(); + $filterSessionArray = $ci->session->userdata(self::SESSION_NAME); + + if (isset($filterSessionArray[$key])) + { + $_getFromSession = $filterSessionArray[$key]; + } + + return $_getFromSession; } /** * */ - private function loadViewSelectFilters($metaData) + private static function _getActiveFilterValue($filterName) { - $this->view('widgets/filter/selectFilters', array('metaData' => $metaData)); + $getActiveFilterValue = ''; + + $activeFields = self::_getFromSession(self::ACTIVE_FILTERS); + + if (isset($activeFields[$filterName])) + { + $getActiveFilterValue = $activeFields[$filterName]; + } + + return $getActiveFilterValue; } /** * */ - private function loadViewTableDataset($dataset) + private static function _loadView($viewName, $parameters) { - $this->view('widgets/filter/tableDataset', array('dataset' => $dataset)); + $ci =& get_instance(); + $ci->load->view($viewName, $parameters); + } + + /** + * + */ + private function _initSession() + { + $filterSessionArray = array(); + + if (isset($_SESSION[self::SESSION_NAME])) + { + $filterSessionArray = $_SESSION[self::SESSION_NAME]; + } + + if (!isset($filterSessionArray[self::SELECTED_FIELDS])) + { + $filterSessionArray[self::SELECTED_FIELDS] = array(); + } + + if (!isset($filterSessionArray[self::SELECTED_FILTERS])) + { + $filterSessionArray[self::SELECTED_FILTERS] = array(); + } + + if (!isset($filterSessionArray[self::ACTIVE_FILTERS])) + { + $filterSessionArray[self::ACTIVE_FILTERS] = array(); + } + + $this->session->set_userdata(self::SESSION_NAME, $filterSessionArray); + } + + /** + * + */ + private function _initFilterWidget($args) + { + if (is_array($args) && count($args) > 0) + { + if (isset($args[self::APP_PARAMETER])) + { + $this->app = $args[self::APP_PARAMETER]; + } + else + { + show_error('The "'.self::APP_PARAMETER.'" parameter must be specified'); + } + + if (isset($args[self::DATASET_NAME_PARAMETER])) + { + $this->datasetName = $args[self::DATASET_NAME_PARAMETER]; + } + else + { + show_error('The "'.self::DATASET_NAME_PARAMETER.'" parameter must be specified'); + } + + if (isset($args[self::QUERY_PARAMETER])) + { + $this->query = $args[self::QUERY_PARAMETER]; + } + else + { + show_error('The "'.self::QUERY_PARAMETER.'" parameter must be specified'); + } + } + else + { + show_error('Second parameter must be an associative array'); + } + } + + /** + * + */ + private function _getSelectedFieldsFromPost() + { + // Selected fields + $selectedFields = array(); + + $filterSessionArray = $this->session->userdata(self::SESSION_NAME); + if (isset($filterSessionArray[self::SELECTED_FIELDS])) + { + $selectedFields = $filterSessionArray[self::SELECTED_FIELDS]; + } + + if (is_array($_POST)) + { + if (array_key_exists(self::CMD_ADD_FIELD, $_POST) && trim($_POST[self::CMD_ADD_FIELD]) != '') + { + if (!in_array($_POST[self::CMD_ADD_FIELD], $selectedFields)) + { + $selectedFields[] = $_POST[self::CMD_ADD_FIELD]; + } + } + + if (array_key_exists(self::CMD_REMOVE_FIELD, $_POST) && trim($_POST[self::CMD_REMOVE_FIELD]) != '') + { + $tmpArray = array(); + foreach ($selectedFields as $key => $value) + { + if ($_POST[self::CMD_REMOVE_FIELD] != $value) + { + $tmpArray[] = $value; + } + } + + $selectedFields = $tmpArray; + } + } + + return $selectedFields; + } + + /** + * + */ + private function _getSelectedFiltersFromPost() + { + // Selected filters + $selectedFilters = array(); + $activeFilters = array(); + + $filterSessionArray = $this->session->userdata(self::SESSION_NAME); + + if (isset($filterSessionArray[self::SELECTED_FILTERS])) + { + $selectedFilters = $filterSessionArray[self::SELECTED_FILTERS]; + } + + if (isset($filterSessionArray[self::ACTIVE_FILTERS])) + { + $activeFilters = $filterSessionArray[self::ACTIVE_FILTERS]; + } + + if (is_array($_POST)) + { + if (array_key_exists(self::CMD_ADD_FILTER, $_POST) && trim($_POST[self::CMD_ADD_FILTER]) != '') + { + if (!in_array($_POST[self::CMD_ADD_FILTER], $selectedFilters)) + { + $selectedFilters[] = $_POST[self::CMD_ADD_FILTER]; + } + } + + if (array_key_exists(self::CMD_REMOVE_FILTER, $_POST) && trim($_POST[self::CMD_REMOVE_FILTER]) != '') + { + $tmpArray = array(); + foreach ($selectedFilters as $key => $value) + { + if ($_POST[self::CMD_REMOVE_FILTER] != $value) + { + $tmpArray[] = $value; + } + } + + $selectedFilters = $tmpArray; + + if (isset($activeFilters[$_POST[self::CMD_REMOVE_FILTER]])) + { + + } + } + } + + return $selectedFilters; + } + + /** + * + */ + private function _getActiveFiltersFromPost() + { + // Selected fields + $activeFilters = array(); + $selectedFilters = array(); + + $filterSessionArray = $this->session->userdata(self::SESSION_NAME); + + if (isset($filterSessionArray[self::ACTIVE_FILTERS])) + { + $activeFilters = $filterSessionArray[self::ACTIVE_FILTERS]; + } + + if (isset($filterSessionArray[self::SELECTED_FILTERS])) + { + $selectedFilters = $filterSessionArray[self::SELECTED_FILTERS]; + } + + if (is_array($_POST)) + { + for ($selectedFiltersCounter = 0; $selectedFiltersCounter < count($selectedFilters); $selectedFiltersCounter++) + { + $selectedFilter = $selectedFilters[$selectedFiltersCounter]; + + if (isset($_POST[$selectedFilter])) + { + $activeFilters[$selectedFilter] = $_POST[$selectedFilter]; + } + } + } + + return $activeFilters; + } + + /** + * + */ + private function _setSessionFilterData() + { + $filterSessionArray = array( + self::SELECTED_FIELDS => $this->_getSelectedFieldsFromPost(), + self::SELECTED_FILTERS => $this->_getSelectedFiltersFromPost(), + self::ACTIVE_FILTERS => $this->_getActiveFiltersFromPost(), + ); + + $this->session->set_userdata(self::SESSION_NAME, $filterSessionArray); + } + + /** + * + */ + private function _generateQuery() + { + $query = $this->query; + // Filters dataset + if (is_array($_POST) + && array_key_exists(self::CMD_APPLY_FILTERS, $_POST) + && $_POST[self::CMD_APPLY_FILTERS] == 'true') + { + if (is_array($_POST) && array_key_exists(self::SELECTED_FILTERS, $_POST)) + { + $selectedFilters = $_POST[self::SELECTED_FILTERS]; + } + + for ($filtersCounter = 0; $filtersCounter < count($selectedFilters); $filtersCounter++) + { + $selectedFilter = $selectedFilters[$filtersCounter]; + + if (isset($_POST[$selectedFilter])) + { + } + } + + $query = 'SELECT * FROM ('.$this->query.') tableFilters WHERE "Vorname" ILIKE \'%Oliver%\''; + } + + return $query; } } From ec00c93d04fd0389fe87a7fbceae36727f4584ce Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 1 Dec 2017 15:15:16 +0100 Subject: [PATCH 05/10] Better check if a table contains data before using the tablesorter --- application/views/templates/header.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/views/templates/header.php b/application/views/templates/header.php index 0cb3a9fad..47befaac7 100644 --- a/application/views/templates/header.php +++ b/application/views/templates/header.php @@ -69,9 +69,9 @@ if($jqueryV1 && $jqueryCurrent)
PersonIdNachnameVornameEmailAktiv
PersonId; ?>Nachname; ?>Vorname; ?>Email; ?>Aktiv === true ? 'True' : 'False'; ?>
{$value2}; ?>