diff --git a/include/class.export.php b/include/class.export.php index 6b7b4be5d54319e6f886046540f0b1daf31f4070..b08291c24980be7790135e67bdadf990872b654f 100644 --- a/include/class.export.php +++ b/include/class.export.php @@ -137,7 +137,7 @@ class Export { 'attachment_count' => __('Attachment Count'), ) + $cdata, $how, - array('modify' => function(&$record, $keys) use ($fields) { + array('modify' => function(&$record, $keys, $obj) use ($fields) { foreach ($fields as $k=>$f) { if (($i = array_search($k, $keys)) !== false) { $record[$i] = $f->export($f->to_php($record[$i])); @@ -182,7 +182,7 @@ class Export { '::getEmail' => __('Email'), ) + $cdata, $how, - array('modify' => function(&$record, $keys) use ($fields) { + array('modify' => function(&$record, $keys, $obj) use ($fields) { foreach ($fields as $k=>$f) { if ($f && ($i = array_search($k, $keys)) !== false) { $record[$i] = $f->export($f->to_php($record[$i])); @@ -221,7 +221,7 @@ class Export { 'name' => 'Name', ) + $cdata, $how, - array('modify' => function(&$record, $keys) use ($fields) { + array('modify' => function(&$record, $keys, $obj) use ($fields) { foreach ($fields as $k=>$f) { if ($f && ($i = array_search($k, $keys)) !== false) { $record[$i] = $f->export($f->to_php($record[$i])); @@ -239,6 +239,38 @@ class Export { return false; } + static function agents($agents, $filename='', $how='csv') { + + // Filename or stream to export agents to + $filename = $filename ?: sprintf('Agents-%s.csv', + strftime('%Y%m%d')); + Http::download($filename, "text/$how"); + $depts = Dept::getDepartments(); + echo self::dumpQuery($agents, array( + '::getName' => 'Name', + '::getUsername' => 'Username', + '::getStatus' => 'Status', + 'permissions' => 'Permissions', + '::getDept' => 'Primary Department', + ) + $depts, + $how, + array('modify' => function(&$record, $keys, $obj) use ($depts) { + + if (($i = array_search('permissions', $keys))) + $record[$i] = implode(",", array_keys($obj->getPermission()->getInfo())); + + $roles = $obj->getRoles(); + foreach ($depts as $k => $v) { + if (is_numeric($k) && ($i = array_search($k, $keys)) !== false) { + $record[$i] = $roles[$k] ?: ''; + } + } + return $record; + }) + ); + exit; + + } } class ResultSetExporter { @@ -276,26 +308,32 @@ class ResultSetExporter { $this->_res->next(); $record = array(); - foreach ($this->keys as $field) { list($field, $func) = explode('::', $field); $path = explode('.', $field); + $current = $object; // Evaluate dotted ORM path if ($field) { foreach ($path as $P) { - $current = $current->{$P}; + if (isset($current->{$P})) + $current = $current->{$P}; + else { + $current = $P; + break; + } } } // Evalutate :: function call on target current if ($func && (method_exists($current, $func) || method_exists($current, '__call'))) { $current = $current->{$func}(); } + $record[] = (string) $current; } if (isset($this->options['modify']) && is_callable($this->options['modify'])) - $record = $this->options['modify']($record, $this->keys); + $record = $this->options['modify']($record, $this->keys, $object); return $record; } @@ -321,17 +359,7 @@ class CsvResultsExporter extends ResultSetExporter { if (!$this->output) $this->output = fopen('php://output', 'w'); - // Detect delimeter from the current locale settings. For locales - // which use comma (,) as the decimal separator, the semicolon (;) - // should be used as the field separator - $delimiter = ','; - if (class_exists('NumberFormatter')) { - $nf = NumberFormatter::create(Internationalization::getCurrentLocale(), - NumberFormatter::DECIMAL); - $s = $nf->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); - if ($s == ',') - $delimiter = ';'; - } + $delimiter = Internationalization::getCSVDelimiter(); // Output a UTF-8 BOM (byte order mark) fputs($this->output, chr(0xEF) . chr(0xBB) . chr(0xBF)); diff --git a/include/class.i18n.php b/include/class.i18n.php index 0a08736d76d84cc4e120cd73215a48a161a659f0..0dc60bde0707e682bd2ce4d774fdafbfce88bc4a 100644 --- a/include/class.i18n.php +++ b/include/class.i18n.php @@ -408,6 +408,30 @@ class Internationalization { return $locale; } + static function getCSVDelimiter($locale='') { + + if (!$locale) // Prefer browser settings + $locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']); + + // Detect delimeter from the current locale settings. For locales + // which use comma (,) as the decimal separator, the semicolon (;) + // should be used as the field separator + $delimiter = ','; + if (class_exists('NumberFormatter')) { + $nf = NumberFormatter::create($locale ?: self::getCurrentLocale(), + NumberFormatter::DECIMAL); + $s = $nf->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); + if ($s == ',') + $delimiter = ';'; + } else { + $info = localeconv(); + if ($info && $info['decimal_point'] == ',') + $delimiter = ';'; + + } + + return $delimiter; + } // getIntDateFormatter($options) // diff --git a/include/class.staff.php b/include/class.staff.php index 5a20d35b5b24e7618143a540f9b4883cc986de71..9d4df38cc19ccdba8dc0095236881e4d4f7e2482 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -449,23 +449,27 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable { return isset($this->locale) ? $this->locale : 0; } - function getRole($dept=null, $useDefault=true) { - $deptId = is_object($dept) ? $dept->getId() : $dept; - if ($deptId && $deptId != $this->dept_id) { - if (isset($this->_roles[$deptId])) - return $this->_roles[$deptId]; + function getRoles() { + if (!isset($this->_roles)) { + $this->_roles = array($this->dept_id => $this->role); + foreach($this->dept_access as $da) + $this->_roles[$da->dept_id] = $da->role; + } + + return $this->_roles; + } - if ($access = $this->dept_access->findFirst(array('dept_id' => $deptId))) - return $this->_roles[$deptId] = $access->role; + function getRole($dept=null) { + $deptId = is_object($dept) ? $dept->getId() : $dept; + $roles = $this->getRoles(); + if (isset($roles[$deptId])) + return $roles[$deptId]; - if (!$useDefault || !$this->usePrimaryRoleOnAssignment()) - // View only access - return new Role(array()); + if ($this->usePrimaryRoleOnAssignment()) + return $this->role; - // Fall through to primary role - } - // For the primary department, use the primary role - return $this->role; + // View only access + return new Role(array()); } function hasPerm($perm, $global=true) { @@ -494,10 +498,14 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable { return TRUE; } - function isactive() { + function isActive() { return $this->isactive; } + function getStatus() { + return $this->isActive() ? __('Active') : __('Locked'); + } + function isVisible() { return $this->isvisible; } @@ -507,7 +515,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable { } function isAvailable() { - return ($this->isactive() && !$this->onVacation()); + return ($this->isActive() && !$this->onVacation()); } function showAssignedOnly() { @@ -1174,6 +1182,15 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable { return true; } + static function export($criteria=null, $filename='') { + include_once(INCLUDE_DIR.'class.error.php'); + + $agents = Staff::objects(); + // Sort based on name formating + $agents = self::nsort($agents); + Export::agents($agents, $filename); + } + } interface RestrictedAccess { diff --git a/include/staff/staffmembers.inc.php b/include/staff/staffmembers.inc.php index 97f7c1265249a845d5bfb49d3705e66638e44569..9c3c76020c4e04ad6d17f014ac9eea413a057073 100644 --- a/include/staff/staffmembers.inc.php +++ b/include/staff/staffmembers.inc.php @@ -143,6 +143,12 @@ $agents->limit($pageNav->getLimit())->offset($pageNav->getStart()); <?php echo __( 'Change Department'); ?> </a> </li> + <li> + <a class="no-pjax" href="staff.php?a=export"> + <i class="icon-download-alt icon-fixed-width"></i> + <?php echo __( 'Export Agents'); ?> + </a> + </li> <!-- TODO: Implement "Reset Access" mass action <li><a class="dialog-first" href="#staff/reset-access"> <i class="icon-puzzle-piece icon-fixed-width"></i> diff --git a/scp/staff.php b/scp/staff.php index 9b2f4a999c6b6d65b10077dc3ededd2769129a89..c2731b9f2d69b7b0ff96d11f35d4c00782c5dd40 100644 --- a/scp/staff.php +++ b/scp/staff.php @@ -171,8 +171,11 @@ if($_POST){ $page='staffmembers.inc.php'; $tip_namespace = 'staff.agent'; -if($staff || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) { +if ($staff || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) { $page='staff.inc.php'; +} elseif ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'export')) { + if (!Staff::export()) + $errors['err'] = sprintf(__('Unable to export %s.'), __('Agents')); } $nav->setTabActive('staff');