diff --git a/workflow/engine/classes/DashletOpenVsCompleted.php b/workflow/engine/classes/DashletOpenVsCompleted.php
new file mode 100644
index 000000000..8194416a6
--- /dev/null
+++ b/workflow/engine/classes/DashletOpenVsCompleted.php
@@ -0,0 +1,294 @@
+xtype = 'arraystore';
+ $contextTimeStore->fields = array ('id','value'
+ );
+ $contextTimeStore->data = array (array ('TODAY', G::LoadTranslation('ID_TODAY')
+ ),array ('YESTERDAY', G::LoadTranslation('ID_YESTERDAY')
+ ),array ('THIS_WEEK', G::LoadTranslation('ID_THIS_WEEK')
+ ),array ('PREVIOUS_WEEK', G::LoadTranslation('ID_PREVIOUS_WEEK')
+ ),array ('THIS_MONTH', G::LoadTranslation('ID_THIS_MONTH')
+ ),array ('PREVIOUS_MONTH', G::LoadTranslation('ID_PREVIOUS_MONTH')
+ ),array ('THIS_YEAR', G::LoadTranslation('ID_THIS_YEAR')
+ ),array ('PREVIOUS_YEAR', G::LoadTranslation('ID_PREVIOUS_YEAR')
+ )
+ );
+
+ $contextTime = new stdclass();
+ $contextTime->xtype = 'combo';
+ $contextTime->name = 'DAS_INS_CONTEXT_TIME';
+ $contextTime->fieldLabel = G::LoadTranslation( 'ID_PERIOD' );
+ $contextTime->editable = false;
+ $contextTime->width = 320;
+ $contextTime->store = $contextTimeStore;
+ $contextTime->mode = 'local';
+ $contextTime->triggerAction = 'all';
+ $contextTime->valueField = 'id';
+ $contextTime->displayField = 'value';
+ $contextTime->value = 'TODAY';
+ $additionalFields[] = $contextTime;
+
+ $redFrom = new stdclass();
+ $redFrom->xtype = 'numberfield';
+ $redFrom->name = 'DAS_RED_FROM';
+ $redFrom->fieldLabel = G::LoadTranslation( 'ID_RED_STARTS_IN' );
+ $redFrom->width = 50;
+ $redFrom->maxLength = 3;
+ $redFrom->maxValue = 100;
+ $redFrom->minValue = 0;
+ $redFrom->allowBlank = false;
+ $redFrom->value = 0;
+ $additionalFields[] = $redFrom;
+
+ $redTo = new stdclass();
+ $redTo->xtype = 'numberfield';
+ $redTo->name = 'DAS_RED_TO';
+ $redTo->fieldLabel = G::LoadTranslation( 'ID_RED_ENDS_IN' );
+ $redTo->width = 50;
+ $redTo->maxLength = 3;
+ $redTo->maxValue = 100;
+ $redTo->minValue = 0;
+ $redTo->allowBlank = false;
+ $redTo->value = 30;
+ $additionalFields[] = $redTo;
+
+ $yellowFrom = new stdclass();
+ $yellowFrom->xtype = 'numberfield';
+ $yellowFrom->name = 'DAS_YELLOW_FROM';
+ $yellowFrom->fieldLabel = G::LoadTranslation( 'ID_YELLOW_STARTS_IN' );
+ $yellowFrom->width = 50;
+ $yellowFrom->maxLength = 3;
+ $yellowFrom->maxValue = 100;
+ $yellowFrom->minValue = 0;
+ $yellowFrom->allowBlank = false;
+ $yellowFrom->value = 30;
+ $additionalFields[] = $yellowFrom;
+
+ $yellowTo = new stdclass();
+ $yellowTo->xtype = 'numberfield';
+ $yellowTo->name = 'DAS_YELLOW_TO';
+ $yellowTo->fieldLabel = G::LoadTranslation( 'ID_YELLOW_ENDS_IN' );
+ $yellowTo->width = 50;
+ $yellowTo->maxLength = 3;
+ $yellowTo->maxValue = 100;
+ $yellowTo->minValue = 0;
+ $yellowTo->allowBlank = false;
+ $yellowTo->value = 50;
+ $additionalFields[] = $yellowTo;
+
+ $greenFrom = new stdclass();
+ $greenFrom->xtype = 'numberfield';
+ $greenFrom->name = 'DAS_GREEN_FROM';
+ $greenFrom->fieldLabel = G::LoadTranslation( 'ID_GREEN_STARTS_IN' );
+ $greenFrom->width = 50;
+ $greenFrom->maxLength = 3;
+ $greenFrom->maxValue = 100;
+ $greenFrom->minValue = 0;
+ $greenFrom->allowBlank = false;
+ $greenFrom->value = 50;
+ $additionalFields[] = $greenFrom;
+
+ $greenTo = new stdclass();
+ $greenTo->xtype = 'numberfield';
+ $greenTo->name = 'DAS_GREEN_TO';
+ $greenTo->fieldLabel = G::LoadTranslation( 'ID_GREEN_ENDS_IN' );
+ $greenTo->width = 50;
+ $greenTo->maxLength = 3;
+ $greenTo->maxValue = 100;
+ $greenTo->minValue = 0;
+ $greenTo->allowBlank = false;
+ $greenTo->value = 100;
+ $additionalFields[] = $greenTo;
+
+ return $additionalFields;
+ }
+
+ public static function getXTemplate ($className)
+ {
+ return "
";
+ }
+
+ public function setup ($config)
+ {
+ $this->redFrom = isset( $config['DAS_RED_FROM'] ) ? (int) $config['DAS_RED_FROM'] : 0;
+ $this->redTo = isset( $config['DAS_RED_TO'] ) ? (int) $config['DAS_RED_TO'] : 30;
+ $this->yellowFrom = isset( $config['DAS_YELLOW_FROM'] ) ? (int) $config['DAS_YELLOW_FROM'] : 30;
+ $this->yellowTo = isset( $config['DAS_YELLOW_TO'] ) ? (int) $config['DAS_YELLOW_TO'] : 50;
+ $this->greenFrom = isset( $config['DAS_GREEN_FROM'] ) ? (int) $config['DAS_GREEN_FROM'] : 50;
+ $this->greenTo = isset( $config['DAS_GREEN_TO'] ) ? (int) $config['DAS_GREEN_TO'] : 100;
+
+ $thisYear = date( 'Y' );
+ $lastYear = $thisYear - 1;
+ $thisMonth = date( 'M' );
+ $lastMonth = date( 'M', strtotime( "31 days ago" ) );
+
+ $todayIni = date( 'Y-m-d H:i:s', strtotime( "today 00:00:00" ) );
+ $todayEnd = date( 'Y-m-d H:i:s', strtotime( "today 23:59:59" ) );
+ $yesterdayIni = date( 'Y-m-d H:i:s', strtotime( "yesterday 00:00:00" ) );
+ $yesterdayEnd = date( 'Y-m-d H:i:s', strtotime( "yesterday 23:59:59" ) );
+ $thisWeekIni = date( 'Y-m-d H:i:s', strtotime( "monday 00:00:00" ) );
+ $thisWeekEnd = date( 'Y-m-d H:i:s', strtotime( "sunday 23:59:59" ) );
+ $previousWeekIni = date( 'Y-m-d H:i:s', strtotime( "last monday 00:00:00" ) );
+ $previousWeekEnd = date( 'Y-m-d H:i:s', strtotime( "last sunday 23:59:59" ) );
+
+ $thisMonthIni = date( 'Y-m-d H:i:s', strtotime( "$thisMonth 1st 00:00:00" ) );
+ $thisMonthEnd = date( 'Y-m-d H:i:s', strtotime( "$thisMonth last day 23:59:59" ) );
+
+ $previousMonthIni = date( 'Y-m-d H:i:s', strtotime( "$lastMonth 1st 00:00:00" ) );
+ $previousMonthEnd = date( 'Y-m-d H:i:s', strtotime( "$lastMonth last day 23:59:59" ) );
+
+ $thisYearIni = date( 'Y-m-d H:i:s', strtotime( "jan $thisYear 00:00:00" ) );
+ $thisYearEnd = date( 'Y-m-d H:i:s', strtotime( "Dec 31 $thisYear 23:59:59" ) );
+ $previousYearIni = date( 'Y-m-d H:i:s', strtotime( "jan $lastYear 00:00:00" ) );
+ $previousYearEnd = date( 'Y-m-d H:i:s', strtotime( "Dec 31 $lastYear 23:59:59" ) );
+
+ if (! isset( $config['DAS_INS_CONTEXT_TIME'] )) {
+ $config['DAS_INS_CONTEXT_TIME'] = 'TODAY';
+ }
+
+ switch ($config['DAS_INS_CONTEXT_TIME']) {
+ case 'TODAY':
+ $dateIni = $todayIni;
+ $dateEnd = $todayEnd;
+ break;
+ case 'YESTERDAY':
+ $dateIni = $yesterdayIni;
+ $dateEnd = $yesterdayEnd;
+ break;
+ case 'THIS_WEEK':
+ $dateIni = $thisWeekIni;
+ $dateEnd = $thisWeekEnd;
+ break;
+ case 'PREVIOUS_WEEK':
+ $dateIni = $previousWeekIni;
+ $dateEnd = $previousWeekEnd;
+ break;
+ case 'THIS_MONTH':
+ $dateIni = $todayIni;
+ $dateEnd = $todayEnd;
+ break;
+ case 'PREVIOUS_MONTH':
+ $dateIni = $todayIni;
+ $dateEnd = $todayEnd;
+ break;
+ case 'THIS_QUARTER':
+ $dateIni = $todayIni;
+ $dateEnd = $todayEnd;
+ break;
+ case 'PREVIOUS_QUARTER':
+ $dateIni = $todayIni;
+ $dateEnd = $todayEnd;
+ break;
+ case 'THIS_YEAR':
+ $dateIni = $thisYearIni;
+ $dateEnd = $thisYearEnd;
+ break;
+ case 'PREVIOUS_YEAR':
+ $dateIni = $previousYearIni;
+ $dateEnd = $previousYearEnd;
+ break;
+ }
+
+ $con = Propel::getConnection( "workflow" );
+ $stmt = $con->createStatement();
+ $sql = "select count(*) as CANT from APPLICATION where APP_STATUS in ( 'DRAFT', 'TO_DO' ) ";
+ $sql .= "and APP_CREATE_DATE > '$dateIni' and APP_CREATE_DATE <= '$dateEnd' ";
+ $rs = $stmt->executeQuery( $sql, ResultSet::FETCHMODE_ASSOC );
+ $rs->next();
+ $row = $rs->getRow();
+ $casesTodo = $row['CANT'];
+
+ $stmt = $con->createStatement();
+ $sql = "select count(*) as CANT from APPLICATION where APP_STATUS = 'COMPLETED' ";
+ $sql .= "and APP_CREATE_DATE > '$dateIni' and APP_CREATE_DATE <= '$dateEnd' ";
+ $rs = $stmt->executeQuery( $sql, ResultSet::FETCHMODE_ASSOC );
+ $rs->next();
+ $row = $rs->getRow();
+ $casesCompleted = $row['CANT'];
+ if ($casesCompleted + $casesTodo != 0) {
+ $this->value = $casesCompleted / ($casesCompleted + $casesTodo) * 100;
+ } else {
+ $this->value = 0;
+ }
+ $this->open = $casesCompleted;
+ $this->completed = $casesCompleted + $casesTodo;
+ switch ($config['DAS_INS_CONTEXT_TIME']) {
+ case 'TODAY':
+ $this->centerLabel = G::LoadTranslation('ID_TODAY');
+ break;
+ case 'YESTERDAY':
+ $this->centerLabel = G::LoadTranslation('ID_YESTERDAY');
+ break;
+ case 'THIS_WEEK':
+ $this->centerLabel = G::LoadTranslation('ID_THIS_WEEK');
+ break;
+ case 'PREVIOUS_WEEK':
+ $this->centerLabel = G::LoadTranslation('ID_PREVIOUS_WEEK');
+ break;
+ case 'THIS_MONTH':
+ $this->centerLabel = G::LoadTranslation('ID_THIS_MONTH');
+ break;
+ case 'PREVIOUS_MONTH':
+ $this->centerLabel = G::LoadTranslation('ID_PREVIOUS_MONTH');
+ break;
+ case 'THIS_QUARTER':
+ $this->centerLabel = G::LoadTranslation('ID_THIS_QUARTER');
+ break;
+ case 'PREVIOUS_QUARTER':
+ $this->centerLabel = G::LoadTranslation('ID_PREVIOUS_QUARTER');
+ break;
+ case 'THIS_YEAR':
+ $this->centerLabel = G::LoadTranslation('ID_THIS_YEAR');
+ break;
+ case 'PREVIOUS_YEAR':
+ $this->centerLabel = G::LoadTranslation('ID_PREVIOUS_YEAR');
+ break;
+ default:
+ $this->centerLabel = '';
+ break;
+ }
+ return true;
+ }
+
+ public function render ($width = 300)
+ {
+ $g = new pmGauge();
+ $g->w = $width;
+ $g->value = $this->value;
+
+ $g->redFrom = $this->redFrom;
+ $g->redTo = $this->redTo;
+ $g->yellowFrom = $this->yellowFrom;
+ $g->yellowTo = $this->yellowTo;
+ $g->greenFrom = $this->greenFrom;
+ $g->greenTo = $this->greenTo;
+
+ $g->centerLabel = $this->centerLabel;
+ $g->open = $this->open;
+ $g->completed = $this->completed;
+ $g->render();
+ }
+
+}
\ No newline at end of file
diff --git a/workflow/engine/classes/PmDashlet.php b/workflow/engine/classes/PmDashlet.php
new file mode 100644
index 000000000..13a75cc35
--- /dev/null
+++ b/workflow/engine/classes/PmDashlet.php
@@ -0,0 +1,402 @@
+dashletInstance = $this->loadDashletInstance( $dasInsUid );
+
+ if (! isset( $this->dashletInstance['DAS_CLASS'] )) {
+ throw new Exception( G::LoadTranslation( 'ID_ERROR_OBJECT_NOT_EXISTS' ) . ' - Probably the plugin related is disabled' );
+ }
+ $className = $this->dashletInstance['DAS_CLASS'];
+
+ if (! class_exists( $className )) {
+ self::setIncludePath();
+ require_once 'classes' . PATH_SEP . 'class.' . $className . '.php';
+ }
+ $this->dashletObject = new $className();
+ $this->dashletObject->setup( $this->dashletInstance );
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ public function render ($width = 300)
+ {
+ try {
+ if (is_null( $this->dashletObject )) {
+ throw new Exception( 'Please call to the function "setup" before call the function "render".' );
+ }
+ $this->dashletObject->render( $width );
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ // Getter and Setters
+
+
+ public function getDashletInstance ()
+ {
+ return $this->dashletInstance;
+ }
+
+ public function getDashletObject ()
+ {
+ return $this->dashletObject;
+ }
+
+ // Own functions
+
+
+ public function getDashletsInstances ($start = null, $limit = null)
+ {
+ try {
+ $dashletsInstances = array ();
+ $criteria = new Criteria( 'workflow' );
+ $criteria->addSelectColumn( '*' );
+ $criteria->addJoin( DashletInstancePeer::DAS_UID, DashletPeer::DAS_UID, Criteria::INNER_JOIN );
+ if (! is_null( $start )) {
+ $criteria->setOffset( $start );
+ }
+ if (! is_null( $limit )) {
+ $criteria->setLimit( $limit );
+ }
+ $dataset = DashletInstancePeer::doSelectRS( $criteria );
+ $dataset->setFetchmode( ResultSet::FETCHMODE_ASSOC );
+ $dataset->next();
+ while ($row = $dataset->getRow()) {
+ $arrayField = unserialize( $row["DAS_INS_ADDITIONAL_PROPERTIES"] );
+
+ if (strstr($row['DAS_TITLE'], '*')) {
+ $row['DAS_TITLE'] = G::LoadTranslationPlugin('advancedDashboards', str_replace("*","",$row['DAS_TITLE']));
+ }
+ $row['DAS_INS_STATUS_LABEL'] = ($row['DAS_INS_STATUS'] == '1' ? G::LoadTranslation( 'ID_ACTIVE' ) : G::LoadTranslation( 'ID_INACTIVE' ));
+ $row['DAS_INS_TITLE'] = (isset( $arrayField['DAS_INS_TITLE'] ) && ! empty( $arrayField['DAS_INS_TITLE'] )) ? $arrayField['DAS_INS_TITLE'] : '';
+ if (! class_exists( $row['DAS_CLASS'] )) {
+ self::setIncludePath();
+ @include 'classes' . PATH_SEP . 'class.' . $row['DAS_CLASS'] . '.php';
+ if (! class_exists( $row['DAS_CLASS'] )) {
+ $dataset->next();
+ continue;
+ }
+ }
+ eval( "\$row['DAS_VERSION'] = defined('" . $row['DAS_CLASS'] . "::version') ? " . $row['DAS_CLASS'] . "::version : \$row['DAS_VERSION'];" );
+
+ switch ($row['DAS_INS_OWNER_TYPE']) {
+ case 'EVERYBODY':
+ $row['DAS_INS_OWNER_TITLE'] = G::LoadTranslation( 'ID_ALL_USERS' );
+ break;
+ case 'USER':
+ require_once 'classes/model/Users.php';
+ $userInstance = new Users();
+ try {
+ $user = $userInstance->load( $row['DAS_INS_OWNER_UID'] );
+ $row['DAS_INS_OWNER_TITLE'] = $user['USR_FIRSTNAME'] . ' ' . $user['USR_LASTNAME'];
+ } catch (Exception $error) {
+ $this->remove( $row['DAS_INS_UID'] );
+ $row['DAS_INS_UID'] = '';
+ }
+ break;
+ case 'DEPARTMENT':
+ require_once 'classes/model/Department.php';
+ $departmentInstance = new Department();
+ try {
+ $department = $departmentInstance->load( $row['DAS_INS_OWNER_UID'] );
+ $row['DAS_INS_OWNER_TITLE'] = $department['DEP_TITLE'];
+ } catch (Exception $error) {
+ $this->remove( $row['DAS_INS_UID'] );
+ $row['DAS_INS_UID'] = '';
+ }
+ break;
+ case 'GROUP':
+ require_once 'classes/model/Groupwf.php';
+ $groupInstance = new Groupwf();
+ try {
+ $group = $groupInstance->load( $row['DAS_INS_OWNER_UID'] );
+ $row['DAS_INS_OWNER_TITLE'] = $group['GRP_TITLE'];
+ } catch (Exception $error) {
+ $this->remove( $row['DAS_INS_UID'] );
+ $row['DAS_INS_UID'] = '';
+ }
+ break;
+ default:
+ $row['DAS_INS_OWNER_TITLE'] = $row['DAS_INS_OWNER_TYPE'];
+ break;
+ }
+ if ($row['DAS_INS_UID'] != '') {
+ $dashletsInstances[] = $row;
+ }
+ $dataset->next();
+ }
+
+ return $dashletsInstances;
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ public function loadDashletInstance ($dasInsUid)
+ {
+ try {
+ $dashletInstance = $this->load( $dasInsUid );
+ //Load data from the serialized field
+ $dashlet = new Dashlet();
+ $dashletFields = $dashlet->load( $dashletInstance['DAS_UID'] );
+ if (is_null( $dashletFields )) {
+ $dashletFields = array ();
+ }
+ return array_merge( $dashletFields, $dashletInstance );
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ public function saveDashletInstance ($data)
+ {
+ try {
+ $this->createOrUpdate( $data );
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ public function deleteDashletInstance ($dasInsUid)
+ {
+ try {
+ $this->remove( $dasInsUid );
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ public function getDashletsInstancesForUser ($userUid)
+ {
+ try {
+ $dashletsInstances = array ();
+ // Include required classes
+ require_once 'classes/model/Department.php';
+ require_once 'classes/model/Users.php';
+ // Check for "public" dashlets
+ $criteria = new Criteria( 'workflow' );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_UID );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_ADDITIONAL_PROPERTIES );
+ $criteria->addSelectColumn( DashletPeer::DAS_CLASS );
+ $criteria->addSelectColumn( DashletPeer::DAS_TITLE );
+ $criteria->add( DashletInstancePeer::DAS_INS_STATUS, '1' );
+ $criteria->addJoin( DashletInstancePeer::DAS_UID, DashletPeer::DAS_UID, Criteria::INNER_JOIN );
+ $criteria->add( DashletInstancePeer::DAS_INS_OWNER_TYPE, 'EVERYBODY' );
+ $dataset = DashletInstancePeer::doSelectRS( $criteria );
+ $dataset->setFetchmode( ResultSet::FETCHMODE_ASSOC );
+ $dataset->next();
+ while ($row = $dataset->getRow()) {
+ if (! isset( $dashletsInstances[$row['DAS_INS_UID']] )) {
+ $arrayField = unserialize( $row["DAS_INS_ADDITIONAL_PROPERTIES"] );
+
+ if (self::verifyPluginDashlet($row['DAS_CLASS'])) {
+ $row['DAS_XTEMPLATE'] = $this->getXTemplate( $row['DAS_CLASS'] );
+ $row["DAS_TITLE"] = (isset( $arrayField["DAS_INS_TITLE"] ) && ! empty( $arrayField["DAS_INS_TITLE"] )) ? $arrayField["DAS_INS_TITLE"] : $row["DAS_TITLE"];
+ $row["DAS_TITLE"] = $row["DAS_TITLE"] . ((isset( $arrayField["DAS_INS_SUBTITLE"] ) && ! empty( $arrayField["DAS_INS_SUBTITLE"] )) ? str_replace( "@@USR_USERNAME", $_SESSION["USR_USERNAME"], $arrayField["DAS_INS_SUBTITLE"] ) : null);
+
+ $dashletsInstances[$row['DAS_INS_UID']] = $row;
+ }
+ }
+ $dataset->next();
+ }
+ // Check for the direct assignments
+ $usersInstance = new Users();
+ $criteria = new Criteria( 'workflow' );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_UID );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_ADDITIONAL_PROPERTIES );
+ $criteria->addSelectColumn( DashletPeer::DAS_CLASS );
+ $criteria->addSelectColumn( DashletPeer::DAS_TITLE );
+ $criteria->addJoin( DashletInstancePeer::DAS_UID, DashletPeer::DAS_UID, Criteria::INNER_JOIN );
+ $criteria->add( DashletInstancePeer::DAS_INS_STATUS, '1' );
+ $criteria->add( DashletInstancePeer::DAS_INS_OWNER_TYPE, 'USER' );
+ $criteria->add( DashletInstancePeer::DAS_INS_OWNER_UID, $userUid );
+ $dataset = DashletInstancePeer::doSelectRS( $criteria );
+ $dataset->setFetchmode( ResultSet::FETCHMODE_ASSOC );
+ $dataset->next();
+ while ($row = $dataset->getRow()) {
+ if (! isset( $dashletsInstances[$row['DAS_INS_UID']] )) {
+ $arrayField = unserialize( $row["DAS_INS_ADDITIONAL_PROPERTIES"] );
+
+ if (self::verifyPluginDashlet($row['DAS_CLASS'])) {
+ $row['DAS_XTEMPLATE'] = $this->getXTemplate( $row['DAS_CLASS'] );
+ $row["DAS_TITLE"] = (isset( $arrayField["DAS_INS_TITLE"] ) && ! empty( $arrayField["DAS_INS_TITLE"] )) ? $arrayField["DAS_INS_TITLE"] : $row["DAS_TITLE"];
+ $row["DAS_TITLE"] = $row["DAS_TITLE"] . ((isset( $arrayField["DAS_INS_SUBTITLE"] ) && ! empty( $arrayField["DAS_INS_SUBTITLE"] )) ? str_replace( "@@USR_USERNAME", $_SESSION["USR_USERNAME"], $arrayField["DAS_INS_SUBTITLE"] ) : null);
+
+ $dashletsInstances[$row['DAS_INS_UID']] = $row;
+ }
+ }
+ $dataset->next();
+ }
+ // Check for department assigments
+ $departmentInstance = new Department();
+ $departments = $departmentInstance->getDepartmentsForUser( $userUid );
+ foreach ($departments as $depUid => $department) {
+ $criteria = new Criteria( 'workflow' );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_UID );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_ADDITIONAL_PROPERTIES );
+ $criteria->addSelectColumn( DashletPeer::DAS_CLASS );
+ $criteria->addSelectColumn( DashletPeer::DAS_TITLE );
+ $criteria->addJoin( DashletInstancePeer::DAS_UID, DashletPeer::DAS_UID, Criteria::INNER_JOIN );
+ $criteria->add( DashletInstancePeer::DAS_INS_STATUS, '1' );
+ $criteria->add( DashletInstancePeer::DAS_INS_OWNER_TYPE, 'DEPARTMENT' );
+ $criteria->add( DashletInstancePeer::DAS_INS_OWNER_UID, $depUid );
+ $dataset = DashletInstancePeer::doSelectRS( $criteria );
+ $dataset->setFetchmode( ResultSet::FETCHMODE_ASSOC );
+ $dataset->next();
+ while ($row = $dataset->getRow()) {
+ if (! isset( $dashletsInstances[$row['DAS_INS_UID']] )) {
+ $arrayField = unserialize( $row["DAS_INS_ADDITIONAL_PROPERTIES"] );
+
+ if (self::verifyPluginDashlet($row["DAS_CLASS"])) {
+ $row['DAS_XTEMPLATE'] = $this->getXTemplate( $row['DAS_CLASS'] );
+ $row["DAS_TITLE"] = (isset( $arrayField["DAS_INS_TITLE"] ) && ! empty( $arrayField["DAS_INS_TITLE"] )) ? $arrayField["DAS_INS_TITLE"] : $row["DAS_TITLE"];
+ $row["DAS_TITLE"] = $row["DAS_TITLE"] . ((isset( $arrayField["DAS_INS_SUBTITLE"] ) && ! empty( $arrayField["DAS_INS_SUBTITLE"] )) ? str_replace( "@@USR_USERNAME", $_SESSION["USR_USERNAME"], $arrayField["DAS_INS_SUBTITLE"] ) : null);
+
+ $dashletsInstances[$row['DAS_INS_UID']] = $row;
+ }
+ }
+ $dataset->next();
+ }
+ }
+ // Check for group assignments
+ $groupsInstance = new Groups();
+ $groups = $groupsInstance->getGroupsForUser( $userUid );
+ foreach ($groups as $grpUid => $group) {
+ $criteria = new Criteria( 'workflow' );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_UID );
+ $criteria->addSelectColumn( DashletInstancePeer::DAS_INS_ADDITIONAL_PROPERTIES );
+ $criteria->addSelectColumn( DashletPeer::DAS_CLASS );
+ $criteria->addSelectColumn( DashletPeer::DAS_TITLE );
+ $criteria->addJoin( DashletInstancePeer::DAS_UID, DashletPeer::DAS_UID, Criteria::INNER_JOIN );
+ $criteria->add( DashletInstancePeer::DAS_INS_STATUS, '1' );
+ $criteria->add( DashletInstancePeer::DAS_INS_OWNER_TYPE, 'GROUP' );
+ $criteria->add( DashletInstancePeer::DAS_INS_OWNER_UID, $grpUid );
+ $dataset = DashletInstancePeer::doSelectRS( $criteria );
+ $dataset->setFetchmode( ResultSet::FETCHMODE_ASSOC );
+ $dataset->next();
+ while ($row = $dataset->getRow()) {
+ if (! isset( $dashletsInstances[$row['DAS_INS_UID']] )) {
+ $arrayField = unserialize( $row["DAS_INS_ADDITIONAL_PROPERTIES"] );
+
+ if (self::verifyPluginDashlet($row["DAS_CLASS"])) {
+ $row['DAS_XTEMPLATE'] = $this->getXTemplate( $row['DAS_CLASS'] );
+ $row["DAS_TITLE"] = (isset( $arrayField["DAS_INS_TITLE"] ) && ! empty( $arrayField["DAS_INS_TITLE"] )) ? $arrayField["DAS_INS_TITLE"] : $row["DAS_TITLE"];
+ $row["DAS_TITLE"] = $row["DAS_TITLE"] . ((isset( $arrayField["DAS_INS_SUBTITLE"] ) && ! empty( $arrayField["DAS_INS_SUBTITLE"] )) ? str_replace( "@@USR_USERNAME", $_SESSION["USR_USERNAME"], $arrayField["DAS_INS_SUBTITLE"] ) : null);
+
+ $dashletsInstances[$row['DAS_INS_UID']] = $row;
+ }
+ }
+ $dataset->next();
+ }
+ }
+ foreach ($dashletsInstances as $key => $field) {
+ $dashletsInstances[$key]['DAS_TITLE'] = htmlentities($field['DAS_TITLE'], ENT_QUOTES, 'UTF-8') . '';
+ }
+ // Check for role assigments
+ // ToDo: Next release
+ // Check for permission assigments
+ // ToDo: Next release
+ return array_values( $dashletsInstances );
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ public static function getXTemplate ($className)
+ {
+ try {
+ if (! class_exists( $className )) {
+ self::setIncludePath();
+ require_once 'classes' . PATH_SEP . 'class.' . $className . '.php';
+ }
+
+ eval( "\$additionalFields = $className::getXTemplate(\$className);" );
+ return $additionalFields;
+ } catch (Exception $error) {
+ throw $error;
+ }
+ }
+
+ public static function verifyPluginDashlet ($className)
+ {
+ // 1-- if name class is in core
+ $fileExist = PATH_CORE . 'classes' . PATH_SEP . 'class.' . $className . '.php';
+ if (file_exists($fileExist)) {
+ return true;
+ }
+
+ // 2-- if name class is in plugin
+
+ //---- verify the name plugin of the class
+ $pluginName = '';
+ $oPluginRegistry = PluginRegistry::loadSingleton();
+ $pluginsDashlets = $oPluginRegistry->getDashlets();
+
+ foreach ($pluginsDashlets as $pluginDashlet) {
+ $fileExist = PATH_PLUGINS . $pluginDashlet . PATH_SEP . 'classes' . PATH_SEP . 'class.' . $className . '.php';
+ if (file_exists($fileExist)) {
+ $pluginName = $pluginDashlet;
+ break;
+ }
+ }
+
+ //---- verify if the plugin is active
+ if ($pluginName == '') {
+ return false;
+ } else {
+ if ($handle = opendir( PATH_PLUGINS )) {
+ while (false !== ($file = readdir( $handle ))) {
+ if (strpos( $file, '.php', 1 ) && is_file( PATH_PLUGINS . $file )) {
+ include_once (PATH_PLUGINS . $file);
+ $pluginDetail = $oPluginRegistry->getPluginDetails( $file );
+ if ($pluginDetail->getNamespace() == $pluginName) {
+ return $pluginDetail->isEnabled();
+ }
+ }
+ }
+ closedir( $handle );
+ }
+ return true;
+ }
+ }
+
+ private static function setIncludePath ()
+ {
+ $oPluginRegistry = PluginRegistry::loadSingleton();
+ $pluginsDashlets = $oPluginRegistry->getDashlets();
+ foreach ($pluginsDashlets as $pluginDashlet) {
+ set_include_path( get_include_path() . PATH_SEPARATOR . PATH_PLUGINS . $pluginDashlet . PATH_SEP );
+ }
+ }
+}
\ No newline at end of file
diff --git a/workflow/engine/classes/PmDrive.php b/workflow/engine/classes/PmDrive.php
new file mode 100644
index 000000000..20cc3d455
--- /dev/null
+++ b/workflow/engine/classes/PmDrive.php
@@ -0,0 +1,268 @@
+folderIdPMDrive != '') {
+ return;
+ }
+
+ $user = new Users();
+ $dataUser = $user->load($usrUid);
+
+ if (!empty($dataUser['USR_EMAIL'])) {
+ $this->setDriveUser($dataUser['USR_EMAIL']);
+ }
+ $this->folderIdPMDrive = empty($dataUser['USR_PMDRIVE_FOLDER_UID']) ? '' : $dataUser['USR_PMDRIVE_FOLDER_UID'];
+
+ $conf = $this->getConfigGmail();
+ $this->folderNamePMDrive = empty($conf->aConfig['folderNamePMDrive']) ? 'PMDrive (' . SYS_SYS . ')' : $conf->aConfig['folderNamePMDrive'];
+
+ if ($this->folderIdPMDrive == '') {
+ $folderid = $this->createFolder($this->folderNamePMDrive);
+
+ $this->folderIdPMDrive = $folderid->id;
+ $dataUser['USR_PMDRIVE_FOLDER_UID'] = $folderid->id;
+ $user->update($dataUser);
+ }
+ }
+
+ public function getFolderIdPMDrive($usrUid)
+ {
+ $this->validateFolderPMDrive($usrUid);
+ return $this->folderIdPMDrive;
+ }
+
+ /**
+ * Set account user
+ *
+ * @param $user email user
+ */
+ public function setFolderNamePMDrive($name)
+ {
+ $conf = $this->getConfigGmail();
+ $conf->aConfig['folderNamePMDrive'] = $name;
+ $conf->saveConfig('GOOGLE_API_SETTINGS', '', '', '');
+
+ $this->folderNamePMDrive = $name;
+ }
+
+ /**
+ * Set account user
+ *
+ * @param $user email user
+ */
+ public function setDriveUser($user)
+ {
+ $this->setUser($user);
+ }
+
+ /**
+ * Instance google service Drive
+ *
+ * @return Google_Service_Drive $service Drive API service instance.
+ */
+ private function serviceDrive()
+ {
+ $client = $this->serviceClient();
+ $service = new Google_Service_Drive($client);
+ return $service;
+ }
+
+ /**
+ * Retrieve a list of File resources.
+ *
+ * @param string $fileId uid file
+ * @return Array List of Google_Service_Drive_DriveFile resources.
+ */
+ public function listFolder($fileId)
+ {
+ $this->setScope(static::DRIVE);
+ $this->setScope(static::DRIVE_FILE);
+ $this->setScope(static::DRIVE_READONLY);
+ $this->setScope(static::DRIVE_METADATA);
+ $this->setScope(static::DRIVE_METADATA_READONLY);
+ $this->setScope(static::DRIVE_APPDATA);
+
+ $service = $this->serviceDrive();
+
+ try {
+ $rows = array();
+ $parameters['q'] = "'" . $fileId . "' in parents and trashed = false";
+ $parents = $service->files->listFiles($parameters);
+
+ foreach ($parents->getItems() as $parent) {
+ $rows = $parent;
+ }
+
+ } catch (Exception $e) {
+ error_log( G::LoadTranslation("ID_MSG_AJAX_FAILURE") . $e->getMessage());
+ }
+ return $rows;
+ }
+
+ /**
+ * Retrieve a list of File resources.
+ *
+ * @param string $name Title of the file to insert, including the extension.
+ * @param string $parentId Parent folder's ID.
+ * @return Google_Service_Drive_DriveFile The file that was inserted. NULL is returned if an API error occurred.
+ */
+ public function createFolder($name, $parentId = null)
+ {
+ $this->setScope(static::DRIVE_FILE);
+
+ $service = $this->serviceDrive();
+
+ $file = new Google_Service_Drive_DriveFile();
+ $file->setMimeType("application/vnd.google-apps.folder");
+ $file->setTitle($name);
+
+ if ($parentId != null) {
+ $parent = new Google_Service_Drive_ParentReference();
+ $parent->setId($parentId);
+ $file->setParents(array($parent));
+ }
+
+ try {
+ $createdFolder = $service->files->insert($file);
+ } catch (Exception $e) {
+ $createdFolder = null;
+ error_log ( G::LoadTranslation("ID_MSG_AJAX_FAILURE") . $e->getMessage());
+ }
+ return $createdFolder;
+ }
+
+ /**
+ * upload new file
+ *
+ * @param string $mime MIME type of the file to insert.
+ * @param string $src location of the file to insert.
+ * @param string $name Title of the file to insert, including the extension.
+ * @return Google_Service_Drive_DriveFile The file that was inserted. NULL is returned if an API error occurred.
+ */
+ public function uploadFile($mime, $src, $name, $parentId = null)
+ {
+ $this->setScope(static::DRIVE_FILE);
+
+ $service = $this->serviceDrive();
+
+ $file = new Google_Service_Drive_DriveFile();
+ $file->setMimeType($mime);
+ $file->setTitle($name);
+
+ // Set the parent folder.
+ if ($parentId != null) {
+ $parent = new Google_Service_Drive_ParentReference();
+ $parent->setId($parentId);
+ $file->setParents(array($parent));
+ }
+
+ $data = file_get_contents($src);
+
+ try {
+ $createdFile = $service->files->insert(
+ $file,
+ array(
+ 'data' => $data,
+ 'mimeType' => $mime,
+ 'uploadType' => 'media'
+ )
+ );
+
+ } catch (Exception $e) {
+ error_log( G::LoadTranslation("ID_MSG_AJAX_FAILURE") . $e->getMessage());
+ }
+ return $createdFile;
+ }
+
+ /**
+ * Download a file's content.
+ *
+ * @param string $fileId id file.
+ * @return String The file's content if successful, null otherwise
+ */
+ public function downloadFile($fileId)
+ {
+ $this->setScope(static::DRIVE);
+ $this->setScope(static::DRIVE_APPDATA);
+ $this->setScope(static::DRIVE_APPS_READONLY);
+ $this->setScope(static::DRIVE_FILE);
+ $this->setScope(static::DRIVE_METADATA);
+ $this->setScope(static::DRIVE_METADATA_READONLY);
+ $this->setScope(static::DRIVE_READONLY);
+ $service = $this->serviceDrive();
+ $response = null;
+
+ try {
+ $file = $service->files->get($fileId);
+ $downloadUrl = $file->getDownloadUrl();
+ if ($downloadUrl) {
+ $request = new Google_Http_Request($downloadUrl, 'GET', null, null);
+ $httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
+ if ($httpRequest->getResponseHttpCode() == 200) {
+ $response = $httpRequest->getResponseBody();
+ } else {
+ error_log(G::LoadTranslation("ID_MSG_AJAX_FAILURE"));
+ }
+ } else {
+ error_log(G::LoadTranslation("ID_PMDRIVE_NO_CONTENT_IN_FILE"));
+ }
+ } catch (Exception $e) {
+ error_log( G::LoadTranslation("ID_MSG_AJAX_FAILURE") . $e->getMessage());
+ }
+ return $response;
+ }
+
+ /**
+ * Insert a new permission.
+ *
+ * @param String $fileId ID of the file to insert permission for.
+ * @param String $value User or group e-mail address, domain name or NULL for "default" type.
+ * @param String $type The value "user", "group", "domain" or "default".
+ * @param String $role The value "owner", "writer" or "reader".
+ * @return Google_Servie_Drive_Permission The inserted permission. NULL is returned if an API error occurred.
+ */
+ public function setPermission($fileId, $value, $type = 'user', $role = 'reader', $sendNotification = false)
+ {
+ $this->setScope(static::DRIVE);
+ $this->setScope(static::DRIVE_FILE);
+
+ $service = $this->serviceDrive();
+ $permission = null;
+
+ $newPermission = new Google_Service_Drive_Permission();
+ $newPermission->setValue($value);
+ $newPermission->setType($type);
+ $newPermission->setRole($role);
+
+ try {
+ $permission = $service->permissions->insert(
+ $fileId,
+ $newPermission,
+ array(
+ 'sendNotificationEmails' => $sendNotification
+ )
+ );
+
+ } catch (Exception $e) {
+ error_log(G::LoadTranslation("ID_MSG_AJAX_FAILURE") . $e->getMessage());
+ }
+ return $permission;
+ }
+}
diff --git a/workflow/engine/classes/PmGoogleApi.php b/workflow/engine/classes/PmGoogleApi.php
new file mode 100644
index 000000000..e8e16433d
--- /dev/null
+++ b/workflow/engine/classes/PmGoogleApi.php
@@ -0,0 +1,245 @@
+verifyfeature('7qhYmF1eDJWcEdwcUZpT0k4S0xTRStvdz09') || $licensedFeatures->verifyfeature('AhKNjBEVXZlWUFpWE8wVTREQ0FObmo0aTdhVzhvalFic1M='))) {
+ G::SendTemporalMessage('ID_USER_HAVENT_RIGHTS_PAGE', 'error', 'labels');
+ G::header('location: ../login/login');
+ die;
+ }
+ $this->loadSettings();
+ }
+
+ public function setScope($scope)
+ {
+ $this->scope[] = $scope;
+ }
+
+ public function getScope()
+ {
+ return $this->scope;
+ }
+
+ public function setUser($user)
+ {
+ $this->user = $user;
+ }
+
+ public function getUser()
+ {
+ return $this->user;
+ }
+
+ public function getConfigGmail()
+ {
+ $this->configuration = new Configurations();
+ $this->configuration->loadConfig($gmail, 'GOOGLE_API_SETTINGS', '');
+ }
+
+ public function setConfigGmail ($id, $value)
+ {
+ $this->configuration->aConfig[$id] = $value;
+ $this->configuration->saveConfig('GOOGLE_API_SETTINGS', '', '', '');
+ }
+
+ public function setServiceAccountEmail($serviceAccountEmail)
+ {
+ $this->setConfigGmail('serviceAccountEmail', $serviceAccountEmail);
+ $this->serviceAccountEmail = $serviceAccountEmail;
+ }
+
+ public function getServiceAccountEmail()
+ {
+ return $this->serviceAccountEmail;
+ }
+
+ public function setServiceAccountCertificate ($serviceAccountCertificate)
+ {
+ $this->setConfigGmail('serviceAccountCertificate', $serviceAccountCertificate);
+ $this->serviceAccountCertificate = $serviceAccountCertificate;
+ }
+
+ public function getServiceAccountCertificate()
+ {
+ return $this->serviceAccountCertificate;
+ }
+
+ public function setServiceGmailStatus($status)
+ {
+ $licensedFeatures = &PMLicensedFeatures::getSingleton();
+ if (!$licensedFeatures->verifyfeature('7qhYmF1eDJWcEdwcUZpT0k4S0xTRStvdz09')) {
+ $status = false;
+ }
+ $this->setConfigGmail('serviceGmailStatus', $status);
+ $this->serviceGmailStatus = $status;
+ }
+
+ public function getServiceGmailStatus()
+ {
+ return $this->serviceGmailStatus;
+ }
+
+ public function setServiceDriveStatus($status)
+ {
+ $licensedFeatures = &PMLicensedFeatures::getSingleton();
+ if (!$licensedFeatures->verifyfeature('AhKNjBEVXZlWUFpWE8wVTREQ0FObmo0aTdhVzhvalFic1M=')) {
+ $status = false;
+ }
+ $this->setConfigGmail('serviceDriveStatus', $status);
+ $this->serviceDriveStatus = $status;
+ }
+
+ public function getServiceDriveStatus()
+ {
+ return $this->serviceDriveStatus;
+ }
+
+ /**
+ * load configuration gmail service account
+ *
+ */
+ public function loadSettings()
+ {
+ $this->getConfigGmail();
+
+ $serviceAccountCertificate = empty($this->configuration->aConfig['serviceAccountCertificate']) ? '' : $this->configuration->aConfig['serviceAccountCertificate'];
+ $serviceAccountEmail = empty($this->configuration->aConfig['serviceAccountEmail']) ? '' : $this->configuration->aConfig['serviceAccountEmail'];
+ $serviceGmailStatus = empty($this->configuration->aConfig['serviceGmailStatus']) ? false : $this->configuration->aConfig['serviceGmailStatus'];
+ $serviceDriveStatus = empty($this->configuration->aConfig['serviceDriveStatus']) ? false : $this->configuration->aConfig['serviceDriveStatus'];
+
+ $this->scope = array();
+
+ $this->serviceAccountEmail = $serviceAccountEmail;
+ $this->serviceAccountCertificate = $serviceAccountCertificate;
+ $this->serviceGmailStatus = $serviceGmailStatus;
+ $this->serviceDriveStatus = $serviceDriveStatus;
+ }
+
+ /**
+ * New service client - Authentication google Api
+ *
+ * @return Google_Service_Client $service API service instance.
+ */
+ public function serviceClient()
+ {
+ $client = null;
+ if (file_exists(PATH_DATA_SITE . $this->serviceAccountCertificate)) {
+ $key = file_get_contents(PATH_DATA_SITE . $this->serviceAccountCertificate);
+ } else {
+ throw new Exception(G::LoadTranslation('ID_GOOGLE_CERTIFICATE_ERROR'));
+ }
+
+ $data = json_decode($key);
+ $assertionCredentials = new Google_Auth_AssertionCredentials(
+ $this->serviceAccountEmail,
+ $this->scope,
+ $data->private_key
+ );
+
+ $assertionCredentials->sub = $this->user;
+
+ $client = new Google_Client();
+ $client->setApplicationName("PMDrive");
+ $client->setAssertionCredentials($assertionCredentials);
+
+
+ return $client;
+ }
+
+ /**
+ * New service client - Authentication google Api
+ *
+ * @param $credentials
+ * @throws \Exception
+ * @return \StdClass response.
+ */
+ public function testService($credentials)
+ {
+
+ $scope = array(
+ static::DRIVE,
+ static::DRIVE_FILE,
+ static::DRIVE_READONLY,
+ static::DRIVE_METADATA,
+ static::DRIVE_METADATA_READONLY,
+ static::DRIVE_APPDATA,
+ static::DRIVE_PHOTOS_READONLY
+ );
+
+ if (file_exists($credentials->pathServiceAccountCertificate)) {
+ $key = file_get_contents($credentials->pathServiceAccountCertificate);
+ } else {
+ throw new Exception(G::LoadTranslation('ID_GOOGLE_CERTIFICATE_ERROR'));
+ }
+ $data = json_decode($key);
+ $assertionCredentials = new Google_Auth_AssertionCredentials(
+ $credentials->emailServiceAccount,
+ $scope,
+ $data->private_key
+ );
+ $assertionCredentials->sub = $this->user;
+
+ $client = new Google_Client();
+ $client->setApplicationName("PMDrive");
+ $client->setAssertionCredentials($assertionCredentials);
+
+ $service = new Google_Service_Drive($client);
+
+ $result = new StdClass();
+ $result->success = true;
+
+ $result->currentUserName = G::LoadTranslation('ID_SERVER_COMMUNICATION_ERROR');
+ $result->rootFolderId = G::LoadTranslation('ID_SERVER_COMMUNICATION_ERROR');
+ $result->quotaType = G::LoadTranslation('ID_SERVER_COMMUNICATION_ERROR');
+ $result->quotaBytesTotal = G::LoadTranslation('ID_SERVER_COMMUNICATION_ERROR');
+ $result->quotaBytesUsed = G::LoadTranslation('ID_SERVER_COMMUNICATION_ERROR');
+
+ try {
+ $about = $service->about->get();
+
+ $result->currentUserName = $about->getName();
+ $result->rootFolderId = $about->getRootFolderId();
+ $result->quotaType = $about->getQuotaType();
+ $result->quotaBytesTotal = $about->getQuotaBytesTotal();
+ $result->quotaBytesUsed = $about->getQuotaBytesUsed();
+ $result->responseGmailTest = G::LoadTranslation('ID_SUCCESSFUL_CONNECTION');
+ } catch (Exception $e) {
+ $result->success = false;
+ $result->responseGmailTest = G::LoadTranslation('ID_SERVER_COMMUNICATION_ERROR');
+ }
+
+ return $result;
+ }
+}