From Cerb Wiki
Cerb (6.7) is a major functionality update released on April 22, 2014. It contains over 106 new features and usability tweaks from community feedback. There are 93 additional improvements provided in 8 maintenance updates.
This is a summary of the most significant improvements. The full release notes may be viewed in the knowledgebase.
- To check if you qualify for this release as a free update, view Setup->System->License Info. If your software updates expire on or after April 22, 2014 then you can upgrade without updating your license.
- Visit the project website to purchase a new license or extend feature updates on your existing license.
- To upgrade your installation, follow the instructions here.
Important Release Notes
- Make a backup before upgrading.
- Cerb now requires the 'mysqli' PHP extension, since the 'mysql' extension is deprecated in PHP 5.5+ and will be removed shortly.
- The cache-related settings in the framework.config.php file are no longer used and may be safely removed. If you were using memcache, you'll need to enable it again from Setup->Configure->Cache.
Spinner images on loading tabs
- [CHD-3321] All tabs that load dynamic content from the server now show a loading "spinner" image while waiting for a response. This gives workers a visual cue that something is happening in the background. Previously, tabs that were loading were either blank or they showed their outdated content until the new content arrived. This improvement is especially helpful on high latency connections.
Variable dashboard columns
- Dashboards can now be configured to display widgets in one, two, three, or four columns. Extra columns are added to the right without rearranging existing widgets. When removing columns from a dashboard, widgets are automatically and evenly redistributed, and can be dragged into a desired order from there. By using one or two columns, more space is available for detailed charts. Four column dashboards can display many compact widgets on a single page without scrolling, and make better use of larger displays.
Background loading of worklists
- [CHD-3065] Worklists are now loaded in order on workspace tabs using an efficient Ajax queue. Previously this process attempted to only load worklists that were visible in the scrolled browser window, but this is no longer necessary with the workspace improvements in 6.x. The loading worklists have a more modern style and an animated "spinner" image.
Cached dashboard widgets
- The content on dashboard widgets is now cached for 60 seconds, which can dramatically improve performance with many concurrent workers. Manually clicking the reload button on a widget will update it with the latest data. When a dashboard is first displayed, any cached content is displayed immediately when the tab first draws. Any widgets with an expired cache are then displayed with a "spinner" image and fetched in sequence through an Ajax pipeline. This process is much more responsive than the previous behavior of waiting until all the widgets have loaded before displaying anything (and leaving workers staring at a mostly blank screen wondering if something is broken). It's also more memory efficient.
- The caching on dashboards can now be configured per-widget. By setting a higher cache TTL (time-to-live) on infrequently used or changed data, page generation performance is improved. The default cache lifetime is set to 60 seconds on every widget during the migration. Refreshing a widget manually automatically uses the latest data and updates the cache.
Miscellaneous workspace improvements
- When a workspace dashboard tab is blank, a helper message is now displayed with instructions on how to modify the number of columns and add new widgets.
- When a new tab is added to a workspace it is now automatically selected. Previously the new tab was highlighted but it still had to be clicked, which was only helpful in a situation where a worker intended to add several tabs at once before modifying any of them. This made the most common use case slightly more difficult.
Export all fields on worklists
- [CHD-2426] [CHD-1993] The export feature on worklists now provides the ability to include all fields and linked records. Previously, only a small subset of the fields were available. For instance, exports can now include custom fields from the ticket's sender's organization. Additionally, large text fields like 'message content' are now available as well. This uses the same underlying functionality as the Web-API, but with the usability of the API. This also fixes the issue where only IDs were available for some fields, which weren't human-readable. A worker may now choose to export IDs, labels, or both.
- [CHD-2426] When exporting a worklist to CSV, JSON, or XML, a picker menu is now displayed to quickly search for and select any number of desired fields. Previously, fields had to be selected from a fixed list of 15 dropdowns. The order of the exported fields can be rearranged by dragging them into place.
- Record IDs are now available as placeholders through the API and when exporting worklists.
Export field labels and types
- [CHD-2426] Work exporting data from a worklist, human-readable labels are now provided for the fields. In CSV format, these are the headings in the first row. For XML and JSON, the labels are provided as a separate object next to the results. Previously, only arcane property names were returned, like 'cf_123'.
- When exporting worklist results in JSON or XML format, field types are included along with the labels. These are useful for interpreting the data; for instance, discerning between a timestamp, checkbox, or number.
Export human readable dates
- When exporting a worklist, an option is now provided to automatically convert timestamps into a human readable format (e.g. "Sun, 06 Apr 2014 02:58:03 -0700"). Previously, timestamps were always in Unix epoch format (e.g. 1396778283), which complicated working with the exported data in programs like Excel.
- Worklist exports in JSON format are now streamed so that peak memory usage remains low. Previously, all the records loaded into memory before they were displayed.
- Worklist exports in XML format are now streamed so that peak memory usage remains low. Previously, all the records loaded into memory before they were displayed.
- Worklist exports now generate output incrementally while displaying the current progress in the browser. This helps to avoid the time and memory constraints inherent in long-running processes. When an export is complete, a download link is shown. Previously, exports attempted to run in a single request, which would become unsuccessful after a list reached a certain size.
Export from all worklists
- [CHD-3337] Snippet records and their content are now exportable from worklists in CSV, XML, or JSON formats.
- Added 'export' functionality to message-based worklists.
- Added 'export' functionality to notification-based worklists.
Event parameters on behaviors
- Events can now display and store customizable parameters per Virtual Attendant behavior. This allows for powerful abstraction. For instance, a single abstract event like 'Record changed' can have a 'Record type' parameter, which allows each behavior to adapt to the conditions and actions of a specific record type. Previously, abstract events could only work with the fields and actions that every type of record had in common (i.e. not very much), and otherwise would require dozens of redundant events like 'Ticket changed', 'Task changed', etc.
- Events can be configured to only trigger when specific parameters match on the listening behaviors. This is useful for new abstract behaviors like 'Record changed' where they may be 30 listeners (one for each type of record), but only one record type is implicated in the current event. Sending the event to only that listener is far more efficient. Previously, an event could restrict itself to one particular behavior (in the case of custom behavior macros), but there was no way to target a collection of behaviors as a related group.
Record changed behaviors
- [CHD-3679] Added a new 'Record changed' event for Virtual Attendant behaviors. This is the first of a series of new abstract events. Instead of having 30+ distinct events for each type of record that can change, all behaviors are created on this single event. The event triggers whenever any record is changed, and each listening behavior specifies which record type it wants to be notified about. When the 'Record changed' behavior specifies its type, all of the conditions and actions from a 'custom behavior' of that type then become available as well. The placeholders of the event provide '(New)' and '(Old)' values for every field, so a behavior can react not just to the fact that a field changed, but also to the fact it changed from a specific earlier value. For instance, a Virtual Attendant behavior could trigger only when tickets move from one specific bucket to another within the same group, or when a 'Priority' custom field changes from 'High' to 'Low'. The possibilities are endless. It's recommended to use the 'Custom script' condition when comparing old and new values.
Custom headers on HTTP request actions
- When using the 'Execute an HTTP request' action in Virtual Attendants, custom headers can now be provided (including placeholders). This makes it possible to integrate with many more web services.
- The Virtual Attendant simulator now only makes conditions editable if they are used by the behavior being tested. For instance, an auto-reply behavior that uses the conditions 'message is new' and 'message is outgoing' will now only show those two values in the simulator, which drastically improves usability. Previously, the values of every possible condition were shown (potentially hundreds) even though most of them weren't useful for testing the current behavior.
- Added a 'secs_pretty' filter to placeholders. This displays a number of elapsed seconds as a human readable label like '2 hours, 5 mins'.
- Fixed the 'xml_decode()' function in placeholder scripts so it doesn't attempt to convert an XML document to an array. It now remains a SimpleXMLElement instance from PHP, which can be iterated, queried with XPath, etc.
- Fixed an issue with the 'xml_decode()' function in placeholder scripts where namespaced XML documents didn't always work with XPath queries.
- Added an 'xml_xpath()' function to placeholder scripts for querying the XML object returned by 'xml_decode()'. This can also return attributes.
More efficient full-text searches
- Full-text search results will now be retrieved as matching IDs before any other filters are applied. In most cases, this is much faster and more efficient than trying to do everything at once. This improvement makes it possible to consistently cache the results of full-text searches, even when other filters on the same worklist change. Previously, each variation of filters would require a different cache, and this could quickly overwhelm the default query cache settings in MySQL. Additionally, full-text results are now sorted by relevancy (best fit for the given search terms) and the top 250 matches are returned. Previously, relevancy wasn't considered at all, and any number of results were returned (even hundreds of thousands), which was very inefficient. The scope can be narrowed by searching for more specific terms. This "pre-fetch" step for full-text searching also makes it very easy for Cerb to integrate with other search engines like Sphinx, Solr, Elasticsearch, etc.
Full-text search index attributes
- Cerb's built-in MySQL full-text search engine now supports attributes (textual or numeric). This makes it possible to segment the indexed content. For instance, the comment content index now has a 'context' attribute, which can restrict text matches to only comments of a specific type (ticket, task, opp, etc). This was a necessary change due to the other improvements in full-text searching, since it would have been possible for search text to match 250 comment records without any of them belonging to the appropriate type of record. Each search schema can define its own attributes, and these will be automatically added when a new fulltext_* table is created. Most specialized search engines (like Sphinx) already have the capability to track attributes, and this change will make it easier for Cerb to seamlessly integrate with them.
Search engine plugins
- New search engine platforms can be added to Devblocks as extensions. The default implementation remains MySQL Fulltext, but plugins can implement native support for Apache Solr, Sphinx, Elasticsearch, Cloudsearch, etc.
- Search functionality can now be configured from Setup->Configure->Search. Indexes are shown for any records that have full-text searchable content, including those contributed by plugins (e.g. message content, kb articles, comment content). A search engine can be configured for each index individually. By default, all content is indexed in the built-in MySQL Fulltext search engine, and no special configurable is necessary. However, dedicated search engines like Sphinx offer more features and higher performance.
Sphinx Search support
- Implemented support for the Sphinx search engine, an open source search server built for speed, scalability, and simple integration. This option requires Sphinx to be installed and configured separately, but you can expect searches to perform several times faster than MySQL Fulltext. Additionally, after switching to Sphinx you can drop the related fulltext_* tables in Cerb's database to reduce memory and storage usage, and to speed up processes like backups. Arbitrary fields can also be indexed by Sphinx and exposed to search (@status @subject @mask @headers, etc). This engine can be selected per-record from Setup->Configure->Search. Refer to the docs for setup instructions.
Quick search with tips per engine and schema
- Search engines can now provide their own quick search examples on a per-field basis. These are shown when a worker selects a fulltext field from the quick search dropdown. For instance, MySQL Fulltext and Sphinx have different search syntaxes. If a search index is moved to Sphinx, workers will be given the appropriate search tips. The quick search examples can also include custom examples per-index, so any additional fields indexed in Sphinx can be provided as examples (e.g. "@subject search text"). Any kind of content can be indexed as a field like this in Sphinx, and Cerb doesn't need to know about it for the queries to work.
Quick search shortcuts
- [CHD-3640] When performing a quick search, clicking on one of the examples in the tooltip will now automatically place it into the text field. This time-saving shortcut is particularly useful for fields like 'status' where a small number of discrete options no longer need to be typed.
Admins can modify worker passwords
- [CHD-3324] Administrators can now change worker passwords from Setup->Workers. In some situations, worker email addresses are also managed by Cerb, so having account recovery information sent there doesn't work. If the password field is left blank on a new worker, then a temporary password will be generated and emailed to them. Some login authenticators (e.g. OpenID, LDAP) will ignore the local password during the login process.
Improved password security
- Password hash information is no longer included in the worker table, model objects, or caches. There is no reason to reference a password hash outside of the login process; and that can involve the database directly, where the results can be discarded afterwards. The more places that password hashes are stored, the more vulnerable they are.
- [CHD-2067] Added a unique "salt" to worker password hashes to make them much more difficult to crack if they are ever exposed.
- Fixed an issue where password hash comparisons were taking place in MySQL rather than in PHP. This could unnecessarily leave password traces in MySQL log files and the process list.
Improved login security
- All logins, successful or not, are now slightly delayed on purpose. This adds an artificial cost to brute force attacks. If successful logins weren't delayed, smart attackers could just abandon a login attempt if it was taking noticeably longer than a successful login would. In the near future, this delay should be increased systematically for each consecutive login failure.
Improved cache security
- The filesystem cache now appends a unique suffix to the generated file names in the storage/tmp/ directory. This helps protect cache file contents in misconfigured environments where the storage/ directory contents are readable by web browsers, since the files no longer have predictable names like 'cache--ch_workers_all'. This is simply a last line of defense against an attacker scanning for sensitive info in the cache, and it doesn't provide any protection if the web server is *very* misconfigured to provide a directory index of all the cache files. Make sure you web server is blocking access to all these directories (api/, features/, libs/, storage/).
Improved session security
- [CHD-3421] The expiration on worker sessions is now automatically extended during activity. Previously, a cookie was set when the worker logged in, and if sessions had an expiration of '1 week', then the cookie would obnoxiously expire at that future time even if the worker happened to be logged in and actively using Cerb. Now the session expiration options are all based on the time elapsed since the last worker activity. If sessions are set to expire after a week of inactivity, then any activity by that worker will extend the expiration by another week.
- Added two new shorter duration session expiration options to Setup->Configure->Security: "after 6 hours of inactivity", and "after 12 hours of inactivity". These are useful now that session expirations only count a continuous period of inactivity.
- When a worker account is deleted, their sessions will now be properly deleted as well.
Improved platform security
- The DevblocksPlatform::importGPC() and ::importVar() helpers can now specify types like array:integer, array:bit, and array:boolean. This will enforce arrays and typecast their contents. This is particularly useful to prevent SQL injection vectors when accepting IDs from an HTML form and sending them to the database. Previously, these variables needed to be sanitized in a second step.
- Made minor cosmetic improvements to the default Support Center stylesheet: removed unnecessary borders and lines; improved button styles; added more padding to content, lists, and sidebars; added more padding to headings; removed underlines from navigation tabs; added more hover effects; stylized worklists.
- Simplified the knowledgebase search options in the Support Center. Previously this displayed "all words", "any words", and "phrase". Cerb will now attempt to determine this automatically like it does on the worker side.
Customize ticket history worklist columns
- [CHD-3687] The Support Center can now be configured to display any combination of fields and custom fields as columns on the Ticket History worklist. For example, this makes it possible to share the value of fields (e.g. owner, priority, first response time) with clients. Previously, the columns on this worklist were limited to the bare minimum (subject, last wrote, updated).
- In the Support Center, when the 'Subject' field is explicitly configured as a column then the worklist will display with records on a single row. Otherwise, the subject is displayed on its own line to make more room available for other columns.
Customize knowledgebase worklist columns
- The Support Center can now be configured to display any combination of fields and custom fields as columns on Knowledgebase worklists.
- In the Support Center, when the 'Title' field is explicitly configured as a knowledgebase column then the worklist will display with records on a single row. Otherwise, the title is displayed on its own line to make more room available for other columns.
- A simple 'Logo URL' setting can now be configured for Support Center portals. Previously, logos could be changed by editing the header.tpl custom template, which was more flexible but also more complicated. That template may still be modified for more complex customizations like mimicking the look and feel of an existing site.
- A 'Favicon URL' setting can now be configured for Support Center profiles to display an icon next to the URL (and in bookmarks). Previously, this had to be configured by modifying the index.tpl custom template, which could cause unnecessary conflicts during an upgrade. This also improves performance because browsers perform an extra HTTP request looking for a favicon when one isn't specified, and the Support Center was going through the work of rendering the home page again in response to these requests.
- The platform-managed settings of each plugin are now cached individually. This allows a plugin to invalidate its cache without requiring the settings of all other plugins to be reloaded from the database. The settings for the 'devblocks.core' plugin are always cached in the local filesystem, so they're available as the platform is starting up. This is where settings are stored for cache engine extensions (which can't load their settings from themselves, before they are set up).
- The cache service can now be instructed to store certain keys in local memory for the duration of the current request. This is useful when the same underlying data is used over a short time period by multiple features without any communication between them (e.g. worklists, Virtual Attendant behaviors). This can also be used when the cached data changes to frequently to persist for a longer period of time, or when the active cache engine can't manage volatile objects.
Cache engine plugins
- New cache engines can now be added through plugins. Caches improve the performance of Cerb by avoiding expensive database queries for content that hasn't been modified. Previously, only caching in the filesystem and memcache were supported. As before, objects are cached to the local filesystem by default without requiring any special configuration. Unlike before, the minimal set of 'bootstrap' caches required by the Devblocks platform are now always cached in the filesystem even when other cachers are available (e.g. plugins, extensions, global settings, tables, and classloader). This makes it possible to gracefully fail to disk-based caching if a previously configured plugin is no longer available, without introducing continuity issues. This also makes it possible to configure caching in a much more usable way from the browser in Setup, and to store cache configuration information in the platform. The cache-related settings in the framework.config.php file are no longer used and may be safely removed. If you were using memcache, you'll need to enable it again.
- Cache engines now declare whether they support volatile content with an isVolatile() method. This allows Cerb to adapt to the type of caching being used. For instance, thousands of cache files won't be created in the local filesystem since this can create I/O bottlenecks (particularly when keys are frequently written, since reads are likely efficiently cached in memory by the OS already). However, hundreds of thousands of cache keys could be written to Redis, Memcached, APC, or XCache without an I/O bottleneck.
- Server-side caching is now configured in Setup->Configure->Cache. Previously this had to be configured from the framework.config.php file, and only the filesystem and Memcached was supported. The cache engines provided by plugins show up here. When configuring a cache engine, its settings are tested before they are saved, and any configuration errors will be reported in the UI.
Filesystem cache improvements
- When content is cached by Cerb in the local filesystem in storage/tmp/, they are now named "cache--*" rather than "devblocks_cache---*". This is mainly aesthetic, but some cache engines do have a slightly higher memory cost for longer key names. Many filesystems have file name length limits around 255 characters. Additionally, the shorter prefix means that files can be distinguished from each other after fewer characters.
- When objects are cached to the filesystem, permissions no longer include 'world-readable' (in Unix parlance, they are chmod 0640). This helps prevent other users on the server from reading their content (Cerb still really shouldn't be installed in a shared hosting environment).
- The filesystem cache engine now supports exclusive locking when writing to files. Previously, in busy environments it was possible (albeit rare) for two webserver processes to simultaneously write to the same cache file, which could lead to inconsistent file contents.
Memcached cache engine
- Memcached-based caching has been implemented as a plugin. It is configurable from Settings->Configure->Cache. The host, port, and key prefix can be set. A key prefix provides a way to namespace keys so that multiple applications can use the same Memcached datastore. A single host:port pair should be set, and a distributed setup should have multiple services placed behind a consistent hashing proxy like Twemproxy. This is a way more reliable way to provide highly available services, as opposed to handling them in the client (i.e. Cerb).
- The Memcached cache engine now generates a unique key prefix every time the cache is globally cleared. This effectively namespaces keys so that old keys will become inactive and be automatically cleaned up. This is proxy- and multi-tenant friendly since the 'flush' command is never used. Objects are now given a default time-to-live of 24 hours to help facilitate this. This approach enables a lot of dynamic content to be cached without concern over exhausting the available memory (e.g. searches, records, worklists). The unique prefix is stored in Memcached, and the automatic namespacing is cluster friendly. If the prefix is lost for any reason (expired, or Memcached restarts) then a new one will be generated automatically and content will be re-cached by Cerb as it is retrieved again.
Redis cache engine
- Redis-based caching has been implemented as a plugin. It is configurable from Settings->Configure->Cache. The host, port, auth, database number, and key prefix can be set. Auth is optional, and useful for publicly hosted Redis databases (like Redis-to-go); although ideally Redis should be configured on an internal IP and be placed behind a firewall. The database number should be left blank when using a proxy in front of Redis, as many don't support multiple databases (and always use number zero). A key prefix provides a way to namespace keys so that multiple applications can use the same Redis datastore. A single host:port pair should be set, and a distributed setup should have multiple services placed behind a consistent hashing proxy like Twemproxy. This is a way more reliable way to provide highly available services, as opposed to handling them in the client (i.e. Cerb).
- The Redis cache engine now generates a unique key prefix every time the cache is globally cleared. This effectively namespaces keys so that old keys will become inactive and be automatically cleaned up (assuming Redis is running in 'maxmemory' mode). This is proxy- and multi-tenant friendly since the 'flush' commands are never used. Objects are now given a default time-to-live of 24 hours to help facilitate this. This approach enables a lot of dynamic content to be cached without concern over exhausting the available memory (e.g. searches, records, worklists). The unique prefix is stored in Redis, and the automatic namespacing is cluster friendly. If the prefix is lost for any reason (expired, or Redis restarts) then a new one will be generated automatically and content will be re-cached by Cerb as it is retrieved again.
Improved platform performance
- [CHD-2955] The full cache of extension properties was being cleared every time any property changed, which created some extra database traffic. This happened often during scheduler /cron jobs. Properties are now cached per-extension, so the invalidation of a cache has no impact on extensions that didn't change.
- Several of the original database tables (e.g. created in 4.x and early 5.x) had a redundant unique index for the 'id' column. This isn't necessary since those tables already have a unique primary key. This added a slight delay when modifying records, and it wasted a little disk space. These redundant indexes are cleaned up by the update.
- The insertion of activity log entries has been optimized. Previously each insertion ran two database queries: one to insert a blank row and retrieve the new ID, and the second to update it. The same insert/update pattern is used elsewhere, but it's not necessary here because activity log records are never modified. This process now happens in a single query.
- Retrieving a worker record by email address now uses the existing worker cache. Previously this was needlessly querying the database.
Improved placeholder performance
- Optimized the way placeholder dictionaries lazy-load content. Previously, cycles were being wasted crawling through linked contexts in the dictionary every time a placeholder was loaded. For instance, if requesting 'ticket_latest_message_sender_full_name' and 'ticket_latest_message_sender_address', data was being recomputed that could have been cached when the dictionary was created. This only cost a few milliseconds, but in some areas that code can run many times (worklist export, API, VA, mobile).
- Optimized the way multiple placeholder dictionaries retrieve their values. The feature was originally designed to be used by Virtual Attendants for a single target, but it now powers the mobile UI, web API, Virtual Attendant list variables, and worklist exports. Previously, each dictionary loaded its values independently, which created a lot of redundant database queries (e.g. multiple tickets loading the same organization or sender information). Now the dictionaries are first analyzed to see what linked records they have in common, and only distinct records are loaded. Duplicates records are served from a high-speed temporary cache.
- The message '_label' placeholder is now lazy loaded when first used. This requires an extra lookup to use the ticket mask in the output, which is inefficient if the placeholder isn't used. This was particularly inefficient in areas like the mobile plugin, API, and Virtual Attendants where there could be a hundred placeholder dictionaries open at the same time.
Improved maintenance performance
- [CHD-2954] [CHD-2549] Improved the performance of the nightly maintenance scheduler job. Previously, this was inefficiently looking for broken links between records by performing expensive table joins.
Improved email parser performance
- Lookups are now cached when checking if an email address is owned by a worker. This functionality is used frequently in the email parser where every bit of extra performance helps.
- Mail routing rules are now cached when processing new email. This functionality is used frequently in the email parser where every bit of extra performance helps. The cache is automatically cleared every 20 minutes in order to rebalance the order that rules are checked in based on how often they match.
- Multiple message headers are now inserted into the database in a single query. Previously, headers were inserted individually. Early profiling shows a 33% reduction in total queries when inserting many tickets at once (which the scheduler does quite often when polling POP3 mailboxes).
- Optimized the method used to compute spam probabilities on incoming mail. Previously, ticket and message data was always retrieved from the database, and scores were always saved directly back to ticket records. Now arbitrary content can be analyzed and the spam score and interesting words are returned without extra database queries being performed. In the parser, the anti-spam fields can be set at the same time as everything else, which eliminates several redundant queries for every message being processed.
- Previously, the anti-spam algorithm split subjects like 'CamelCapsWordsWithoutSpaces' into multiple words before analyzing them. Our research shows that these spam subjects haven't been popular for many years, so this code has been removed. Additionally, this approach had the side-effect of not analyzing words at all when they alternated cases every letter 'LiKe tHiS'. This content is now converted to lower-case and compared like normal. The subject of an email message generally only represents a small portion of its overall content, and this change shouldn't have a negative impact on spam classification.
- The parser's mail routing behavior no longer directly modifies records in the database. Instead, changes are made to the in-memory 'model' that the parser manages before a ticket is created. Any custom field values that are set from routing are now handled by the same code that sets custom fields on mail filtering behaviors (combining both actions into a single operation).
- Previously, the mail parser created a ticket record in several steps (ID, meta, message links, spam score, group and bucket). For instance, this prevented Virtual Attendants from detecting ticket changes too early in the process before the associated records were also inserted (custom fields, messages, activity log, etc). While this worked, it had the downside of being quite inefficient, because event listeners and Virtual Attendants still reacted to every record change, but just ignored those events when the fields they cared about weren't present. After a few design changes in the parser, tickets are now created in a single step, after all their related records have been created. This is far more efficient, and early profiling shows a decent performance gain.
Improved search performance
- The results of full-text searches are now cached. With a volatile cache engine (Redis, Memcached) they are cached for 5 minutes, and otherwise they expire at the end of the current request. This solves the long-standing issue where full-text searches were being performed twice when subtotals were enabled. In 6.7+, full-text search filter run first, so their results can be cached consistently regardless of other factors. This means that if more than one worker searches for the same thing, the intermediate results are shared, even if the rest of their worklist filters differ. Additionally, when a worker changes pages, and adds or removes filters, the expensive search no longer needs to run again. This is a major performance improvement, since most logged 'slow queries' are the result of full-text searches being repeated (by subtotals, and by workers changing other filters). For the best performance, you should enable a memory-based cache engine from Setup->Configure->Cache.
Improved Support Center performance
- The Support Center now caches visitor session lookups globally for the duration of the request. Previously, features could load the session from the database multiple times.
Improved worklist performance
- When a worklist has only one page of results with fewer rows than the paging limit (e.g. 6 rows out of 10), then an extra database query will no longer be executed to compute the total rows. The total records is simply the number of results on the first page. The extra query generally wasn't expensive in most cases, but it could potentially have run thousands of times per day on a moderately busy system.
Improved Virtual Attendant performance
- The code that retrieves a list of watchers for a record has been optimized. Previously, this was inefficiently finding results with a JOIN between links and worker records, which always bypassed the worker cache. It could also run a second query to retrieve worker data in some situations. The links are now retrieved as IDs without a JOIN, and the worker cache is always used to return record data.
- Previously, the target record of a Virtual Attendant event (like "New mail received by group") was always pre-loaded before the behaviors ran. Even though the behaviors efficiently shared the same record while running, this was still inefficient when no behaviors existed on the event point, because the data was still loaded anyway. The target record is now only "lazy loaded" from the database when it is first requested (which means at least one active Virtual Attendant behavior is watching the event). This change sped up the email parser by 200-300% during development profiling, and it should improve the performance of everywhere VAs are used in Cerb.
- Virtual Attendant 'contexts' (the available fields and labels of a related set of records) are now cached in-memory for the duration of a request. This is particularly efficient in the parser, where the same VA behaviors might run hundreds of times in one /cron request. These contexts generally don't take long to build, but there is no reason to repeat that process hundreds of times when the cost of temporarily storing them in memory is negligible. This mainly saves CPU cycles.
- Optimized the way changes are detected on ticket records. Previously, every time a record was updated it was first retrieved from the database, and then its original and new values were computed for each field. This was inefficient because there are only a few important fields that trigger functionality (move, assign, change status). Internal fields used by Cerb also no longer trigger the expensive 'changed field' checks (e.g. elapsed time, merging, splits). When important field changes do happen, existing objects are efficiently reused rather than performing redundant lookups.
- Improved the performance of Virtual Attendants by not generating their internal data twice. The existing event wasn't being passed to the running behavior when responding to an event, or in the simulator. This meant that every behavior was generating their own copy of the event. In the simulator, this caused placeholder data to load twice.
- Improved the way that incoming email relay messages are authorized. Previously, the 'Message-ID:' header included the internal ticket ID, and the security hash used the worker's password to sign it. This meant when a worker changed their password the could no longer reply to any pre-existing relay messages.
- Incoming email relay replies are now associated with the message they were based on. This allows features like response times to be calculated properly. Previously, a relay reply was always associated with the latest message on a ticket.
- Fixed an issue on calendars where a long-running event wouldn't display properly on multiple days if it started and ended in a different daylight savings time mode. For instance, an event that started the day before DST and ran for two weeks would only display on a single day in the calendar. This affected both manual events and events synced from worklists (e.g. tickets).
- [CHD-3386] Quick search can be used to filter by calendar on calendar event and recurring event worklists.
- When composing mail, the text on the submit button now reads "Send message" instead of "Save changes". The latter confused some workers into believing a draft would be saved rather than sending the message.
- It's very common for JSON objects to be saved as plugin settings. The 'DevblocksPlatform::setPluginSetting()' and 'DevblocksPlatform::getPluginSetting()' methods now support an additional argument for automatically encoding and decoding JSON-based settings. This saves some redundant code when those settings are loaded or used in multiple places.
- Updated the Twig template engine from 1.8.2 (2012-05-29) to 1.15.1 (2014-02-13).
Cerb (6.7.1) is a maintenance update released on April 27, 2014; it contains 5 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [Platform/Dependencies/Twig] Fixed an issue with the Twig library in PHP 5.4+.
- [Virtual Attendants/Variables] Fixed an issue when editing Virtual Attendant behaviors where adding a new variable replaced the existing ones.
- [Login/Recovery] Fixed an issue that was preventing newly created workers from logging in or recovering their accounts.
- [CHD-3586] [Virtual Attendants/Import] When importing a Virtual Attendant behavior, errors will now be properly displayed in the popup. Previously, when an error occurred the popup would closed and the behavior wouldn't be created, and no explanation was given.
- [Virtual Attendants] Fixed an issue with Virtual Attendant behaviors that used themselves as the 'On:' target in actions. The placeholder had changed in 6.7.
Cerb (6.7.2) is a maintenance update released on May 5, 2014; it contains 21 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [CHD-3636] [Mail/Relay] Relayed messages are now always sent to workers using Cerb as the 'From:' address. Previously, the original sender was spoofed, and this could cause problems with threading (in the worker's email reader) and mail server authentication. It was also confusing to many workers who believed that customers were emailing them directly. By default, the sender information is now included in the '##' template at the top of the message. Existing relay actions on Virtual Attendant behaviors will need to reproduce this manually by using a placeholder for the sender.
- [CHD-3744] [Web-API/Tickets] The 'is_waiting' field on ticket records can now be updated and filtered through the Web-API.
- [CHD-3752] [Mail/HTML] Fixed an issue with external image links in HTML replies where the Markdown URL was being stripped out of the message stored by Cerb. These are properly converted to plaintext URLs now.
- [CHD-3693] [Mail/HTML] When a worker has the "Always switch to HTML mode" setting enabled, this will now also apply to the compose popup.
- [CHD-3749] [Custom Fields/Links/VAs/Worklists] Virtual Attendant behaviors, snippets, and worklist exports can now use all of the placeholders from record link custom fields. Previously these labels were not displayed due to issues with infinite recursion. This feature be used in many ways; for instance: tasks can have a record link custom field for a precursor task; time tracking entries can have a record link custom field to a client organization for billing responsibility; organizations can have a record link custom field to a parent org; etc. Record link custom fields are similar to the 'Links' tab on profiles, except they formalize a link between two records and provide usable placeholders for the linked record as if they came from native fields on that record. A time tracking record that links to an org can reference any of that org's fields and custom fields. Record links are only provided to two levels (to prevent clutter in labels), but custom behaviors can be run by a Virtual Attendant on a linked record to access its deeper record link custom fields.
- [Web-API/Calendars] Fixed an issue when loading calendar custom fields through the Web-API.
- [Platform/Plugins] The DevblocksPlatform::strAlphaNum() convenience function now takes an optional argument for the text to replace invalid characters with. By default this is blank, which just removes invalid characters. Using '_' instead will replace non-alphanumerics with underscores. This is particularly convenient when the passed string is in a known format, like dot-notation (e.g. plugin.extension.name).
- [CHD-3741] [Web-API/Subtotals/Search] It is now possible to retrieve subtotals when searching records through the Web-API. This greatly improves integration with external monitoring, reporting, and dashboards. For instance, open tickets can be searched and subtotaled by group/bucket, which makes it easy to chart these values over time. Worker reply performance can also be charted through subtotals in the same way. Subtotals can be retrieved with the search results, and multiple subtotal sets can be retrieved in a single request.
- [Web-API/Performance] Improved performance in the Web-API by loading a full page of records from the database in a single query. Previously, each record's placeholder dictionary was being loaded individually.
- [Web-API/Usability] Implemented a 'show_meta' option for search requests in the Web-API. This toggles the inclusion of placeholder label and type information as 'records_meta'. For instance, a client can cache meta information after the first page of results, and save bandwidth on subsequent requests by not including the redundant meta again. This option defaults to enabled.
- [Web-API/Usability] Implemented a 'show_results' option for search requests in the Web-API. This toggles the inclusion of records in the response, which is useful with the new subtotals feature if record data is not desired as well. This option defaults to enabled.
- [Web-API/Attachments] Fixed an issue with searching attachments in the Web-API.
- [Web-API/Addresses] Implemented the ability to update and filter by the 'is_defunct' field on address records in the Web-API.
- [Web-API/Messages] Implemented the ability to update and filter by the 'is_broadcast', 'is_outgoing', and 'worker_id' fields on message records in the Web-API.
- [Web-API/Notifications] Implemented the ability to search notification records in the Web-API.
- [Web-API/Attachments] When searching for attachment links using the Web-API, attachment filters can now be used: guid, display_name, mime_type, sha1_hash, size, storage_extension, storage_key, storage_profile_id, and updated.
- [Web-API/Attachments] When displaying attachment links using the Web-API, attachment placeholders can now be expanded. Previously this just displayed the attachment link information and required additional requests to load full details.
- [Web-API/Usability] The Web-API will now properly remove nested _labels and _types from objects and search results when they are lazy-loaded. Previously these were being repeated on every search result, despite the 'results_meta' key providing the same values.
- [Web-API/Usability] In the Web-API, the 'show_meta' option now works when retrieving individual records as well. This removes the '_labels' and '_types' dictionaries that describe the keys, which saves bandwidth if this information is already known (e.g. cached in the client).
- [Web-API/Usability] Fixed an issue in the Web-API where lazy-loaded 'message' objects always showed 'ticket' placeholders even if the messages were already contained inside a ticket. This didn't cause any problems, it just added a bunch of redundant placeholders (e.g. ticket->message->ticket).
- [Extras/Automation] Updated the SQL automation scripts for 6.7.2 in /install/extras/automation/. These scripts enable the automated creation of a new environment without running the guided installer.
Cerb (6.7.3) is a maintenance update released on May 12, 2014; it contains 10 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [Web-API/Attachments] Fixed an API issue with searching attachments. The second page of results was being displayed first.
- [Web-API/Contexts/Custom Fields] The '/contexts/list.json' request in the Web-API now includes custom fields and fieldsets for each object context. This is the recommended way to determine the available custom fields for a given record type. Since all the available custom fields and fieldsets are returned in a single response, this can be efficiently cached by the client.
- [Web-API/Calendars] Calendar objects may now be filtered by owner during Web-API searches.
- [Web-API/Addresses] Address objects may be subtotaled by sender last name while searching in the Web-API.
- [Web-API/Addresses] The 'is_defunct' field may be set on address objects in the Web-API.
- [CHD-3756] [Mail/Parser] Fixed an issue with Outlook calendar attachments. Previously, these attachments had no filename. Now they're given a default of 'calendar.ics', which can automatically open them in programs like Outlook and Apple Calendar.
- [CHD-3736] [Custom Fields/Usability] URLs in text-based custom fields will now be automatically hyperlinked when displayed on worklists or profiles.
- [CHD-3735] [Profiles/Custom Fields/Usability] Multiple-line custom fields displayed at the top of profiles now offer an 'expand' option to display their entire contents with preserved whitespace and hyperlinked URLs.
- [CHD-3746] [Setup/Workers] When editing worker records in configuration, whitespace is removed in email addresses. Previously, a misplaced space at the end of an email address would prevent a worker from being able to log in.
- [Setup/Community Portals] Fixed an issue when configuring Community Portals where the 'Installation' tab could should the wrong port. This was using the current server's port, which may be a PHP application server behind a load balancer. Now the Devblocks URL service is used to detect the port in the public URL.
Cerb (6.7.4) is a maintenance update released on May 19, 2014; it contains 12 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [UI/Peeks] Fixed an escaping issue in the titles of several peek popups. Characters like apostrophes, angle brackets, and quotes were being displayed as HTML entities. Most often this occurred on the Virtual Attendant simulator popup.
- [CHD-3759] [Virtual Attendants/Mail/Owner] The 'Set owner' action on Virtual Attendant ticket- and message-based behaviors can now use worker-based placeholders. For example, if there's an 'Account manager' worker custom field on organizations, then the owner of new incoming tickets can be automatically set to to the sender's org's account manager by using placeholders. Previously this required a rather complex Virtual Attendant behavior to accomplish the same thing.
- [Virtual Attendants/Simulator] Fixed an issue on the Virtual Attendant simulator with the 'Set owner' action of ticket- and message-based behaviors. If a behavior variable was used to set the worker, its value wasn't being displayed.
- [Web-API/Code Cleanup] Fixed a PHP warning if an invalid 'file_id' parameter was given when creating a new ticket from the Web-API.
- [Web-API/Mail/Reply] Implemented a '/tickets/reply.json' request in the Web-API to simplify sending worker replies to ticket messages. This supports all of the options on the reply form from the UI: to/cc/bcc, set custom fields, set owner, move to, set status, reopen at, etc.
- [CHD-3157] [Mail/Usability] When using the 'Save without sending' option on mail replies, those messages are now tagged as 'saved' rather than 'sent' in the conversation history. This feature is often used to add sensitive information to the ticket history that the recipients can only access through the Support Center using SSL. Previously, there was no way to tell which messages were sent or only saved.
- [CHD-3764] [Mail/Compose] The compose popup now requires a 'To:' recipient if the 'Cc:' or 'Bcc:' fields are used. Previously, if the 'To:' was blank then a ticket would be created but no mail was sent at all (regardless of Cc:/Bcc:).
- [CHD-3761] [ACL/Mail] The 'Save without sending' action on ticket replies is now a configurable permission in roles. The action can be granted or denied to specific workers.
- [CHD-3760] [Setup/Workers/Usability] When creating or modifying a worker record, their first and last name will be set on their email address record as well (if blank).
- [Simulator] Tweaked the name generators in the simulator to create more cosmopolitan names. Added a few new phonetics and industries to the organization name generator.
- [Virtual Attendants/Mail/Relay] Fixed an issue with the 'Relay mail to worker' action in certain Virtual Attendants behaviors. This was showing errors in the simulator after a code change in 6.7.2.
- [CHD-3762] [Mail/Relay] The 'From:' sender on relay messages is now configurable from Setup->Mail->Relay. In the 6.7 update, this behavior changed to always relay as the default reply-to in Cerb. Prior to 6.7, the 'From:' address was always spoofed as the original sender (which could cause problems with mail server authentication, failing anti-spam, and not threading properly in mail readers like Gmail). Now there is a blurb in Setup outlining the differences, and then an administrator can select either method.
Cerb (6.7.5) is a maintenance update released on May 26, 2014; it contains 12 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [CHD-3767] [Setup/Sessions] Fixed an error when deleting sessions from the worklist on Setup->Configure->Sessions.
- [CHD-3772] [Time Tracking/Bulk] Fixed an issue where bulk updating Time Tracking worklists always cleared the activity if one wasn't set.
- [CHD-3696] [Mail/Parser] Fixed an issue with received mail that is encoded in 'Windows-1252'. Microsoft products like Outlook and Word use special characters for quotes, dashes, and ellipses. These are now properly converted to their ASCII/UTF-8 equivalents. In some environments, these special characters were truncating messages when a special character was encountered. In others, the special characters were being replaced with a different symbol (e.g. smart quotes as a Euro currency symbol).
- [Mail/Print] Fixed a issue on the ticket print page that prevented the group and bucket fields from showing properly.
- [Web-API/Search] Fixed an issue when searching in the Web-API where the 'sortAsc' parameter doesn't properly sort the results in ascending or descending order. This is because MySQL doesn't guarantee that results will be returned in the same order as an IN(...) statement. The array is now sorted into the same order as the passed IDs.
- [CHD-3690] [Mail/Compose/ACL] Workers can only compose mail from groups that they are a member of.
- [CHD-3704] [Workspaces/Dashboards/ACL] Fixed an issue where unprivileged workers could modify workspace dashboards and widgets.
- [CHD-3701] [Snippets/ACL] Fixed an issue where unprivileged workers had the appearance of being able to modify snippet records. They were shown the editor, but changes were not saved. Now they are shown a read-only popup instead.
- [CHD-3578] [Pages/Usability] Fixed an issue with drag-reordering workspace page menu items in Firefox. When releasing the dragged menu item into a new position, Firefox would often reload the page before the new position was saved. We now ignore click events when dragging.
- [CHD-3732] [Mail/Merge] If any of the tickets being merged were open then the resulting ticket is now always open. Previously the status of the most recently updated ticket was used, but this could result in open tickets being prematurely closed.
- [CHD-3714] [Mail/Worklists/Search] Fixed an issue with filtering ticket worklists by 'Status is not'. For instance, "not deleted or waiting" was filtering as "not deleted OR not waiting". Now it's properly treated as "not deleted AND not waiting".
- [CHD-3713] [Worklists/Search] Fixed an issue with quick search and numeric fields when operators were used. For instance, a quick search on a ticket worklist for "# Messages > 10" was always searching for "> 0" instead.
Cerb (6.7.6) is a maintenance update released on June 2, 2014; it contains 12 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [CHD-3787] [Virtual Attendants/Record Changed] Fixed an issue in 'Record changed' Virtual Attendant behaviors where some '(Old)' prefixed conditions couldn't be configured properly if they were implemented specially by the delegate behavior. For instance '(Old) Ticket status' couldn't be used on a ticket-based 'Record changed' behavior.
- [Virtual Attendants] Fixed an issue with the 'ticket spam score' condition on ticket-based Virtual Attendant behaviors.
- [Custom Fields/Usability] The custom field types are now automatically sorted in alphabetical order.
- [Plugins/SDK] Fixed a typo in the devblocks-dao.php helper script (for plugin developers).
- [CHD-3793] [Virtual Attendants/Custom Fields] Temporarily hid 'Record link' custom fields from Virtual Attendant 'Set field' actions. These weren't supported as actions yet, but will be in the 6.8 update.
- [CHD-3803] [Web-API/Messages/Tickets] Fixed an issue on message requests in the the Web-API where placeholder prefixes like 'ticket_initial_message' could be repeated multiple times.
- [Virtual Attendants/Usability] The placeholder labels are now named more consistently on Virtual Attendant conditions and actions. Previously, some custom fields were named 'Group custom field' while built-in fields were named 'Ticket group name'. This made filtering the placeholder list more difficult.
- [Virtual Attendants/Usability] The 'On:' targets in Virtual Attendant actions are now sorted alphabetically.
- [CHD-3792] [Virtual Attendants/Actions/Custom Fieldsets] Virtual Attendant behaviors that use the 'Create task', 'Create ticket', or 'Create call' actions will now handle custom fieldsets properly. Previously, custom fields from fieldsets were mixed together with global custom fields, and these actions always linked every fieldset to the created record.
- [CHD-3802] [Support Center/History/Activity Log] When a contact is logged into the Support Center and uses the close/reopen button from their ticket history, these actions will now be added to the Activity Log with the contact as the actor. Previously this was showing "Cerb changed ticket to status open/closed", which led workers to believe that Cerb was automatically closing tickets (when contacts were actually doing it).
- [Platform/Plugin Development/Activity Log] Implemented CerberusContexts::pushActivityDefaultActor($context,$context_id) and CerberusContexts::popActivityDefaultActor() for changing the default actor for the Activity Log. The stack allows recursive delegation of actors (e.g. worker->VA->worker). Previously, when the default actor was reset it had no history and always went back to NULL. Now the parent actor is changed back to the default automatically.
- [CHD-3776] [Migration/Search/Worklists] Fixed an issue where search worklists for tickets and messages had permanent required filters based on a worker's group memberships. If new groups were added, this wasn't immediately reflected in the worklists and those tickets could be hidden. In current 6.x, worklists are now filtered by group by default as an editable/removable filter.
Cerb (6.7.7) is a maintenance update released on June 9, 2014; it contains 8 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [CHD-3807] [Dashboards/Firefox] Fixed an issue with mouse position events on certain dashboard widgets in Firefox 29. For instance, on pie charts and scatterplots, only the horizontal mouse position was being considered.
- [Mail/Relay] Fixed an issue where inbound worker relay messages weren't properly processed if the subject line didn't contain a ticket mask, or it contained multiple masks and the right-most mask was invalid. Cerb shouldn't require a mask in the subject line, but a bug was preventing it from looking up the ticket for relay replies using the normal reply headers. This caused all message threading to be based on the subject, and exposed an issue where multiple masks in the subject broke relays.
- [Mail/Relay] Fixed an issue with worker mail relay authentication where intentional randomness in the 'Message-Id:' could lead to inconsistent hash lengths. This would prevent some worker replies from external accounts from parsing properly, in a seemingly difficult to reproduce way (i.e. "sometimes it works, sometimes it doesn't").
- [Setup/Custom Fields] Fixed an issue when editing custom fields in Setup where the 'select all/none' checkbox stopped working properly if it was clicked multiple times.
- [Settings/Watchers] Fixed an issue on the 'Watcher Notifications' tab in worker Settings where the state of the event text didn't change between bold and normal when toggled by clicking the checkbox or using 'select all/none'.
- [CHD-3814] [Worklists/Bulk Update] Fixed an issue where toggling the 'select all/none' checkbox on a worklist multiple times could result in rows appearing selected but not being sent to the server on an action. This also caused an issue in Bulk Update where the 'Whole list' option could be come selected rather than 'Only checked', even though only a few rows appeared to be selected.
- [CHD-3489] [Worklists/Profiles/Custom Fields/Usability] File-based custom fields will now display their file name on profile summaries and when used as worklist columns. Previously only the file size was displayed.
- [Mail/HTML/Usability] Removed the 'Ctrl+E' shortcut for "Link to an External Image" in HTML messages because this interferes with the Ctrl+A (home) and Ctrl+E (end) shortcuts in OS X and Linux.
Cerb (6.7.8) is a maintenance update released on June 23, 2014; it contains 13 minor features, fixes, and usability enhancements from community feedback covering the recent 6.7 update. You can follow these instructions to upgrade.
- [CHD-3821] [Time Tracking/Comments] Fixed an issue where time tracking entries that contained a percent sign (%) in the notes wouldn't be added as comments on the linked record.
- [CHD-3818] [Workspaces/Dashboards/Usability] When a workspace dashboard tab is empty, a different helper message is now shown to workers who don't have edit privileges. Previously, the helper message instructed everyone how to add content, even if they couldn't.
- [CHD-3819] [Workspaces/Usability] When a workspace page is blank, a helper message is now shown to workers who lack edit privileges. Previously, a helper message was only shown on the '+' tab to workers who could add new content, and everyone else was shown a confusingly blank page.
- [CHD-3825] [Virtual Attendants/Create Ticket] Fixed an issue in Virtual Attendant behaviors that use the 'Create ticket' action. Custom fields and record links were being set *after* the new outgoing message was sent, so any other behaviors watching for new messages weren't able to use those custom field values and links to make decisions. For instance, if a macro created a new ticket and linked it to the running Virtual Attendant, a 'New message on a group convo' event wasn't aware of the link because it ran before the link was set. This now works as expected, and custom fields and links are set before the outgoing message is sent.
- [Scheduler/Import] Fixed some PHP warnings in the 'Background Importer' scheduler job when import XML files don't contain the optional 'attachments' or 'comments' tags.
- [Code Cleanup/Notifications] Fixed a PHP warning in notifications when an invalid query was executed. For instance: "WHERE id IN ()".
- [Web-API/Search/Tickets] Fixed an issue where Web-API searches for tickets and groups could become cached with outdated group permissions.
- [Virtual Attendants/HTTP Requests/Simulator] Fixed an issue where any provided custom headers on the Virtual Attendant 'Execute HTTP Request' action weren't being sent when using the simulator. The headers were sent properly otherwise. This made testing and debugging these behaviors unnecessarily complicated.
- [Virtual Attendants/XML] In Virtual Attendant scripts, the xml_decode($text, $namespaces) function can now accept an array of namespaces as the second argument. This array should have prefixes as the keys and namespace URLs as the values (e.g. "weather":"http://ws.cdyne.com/WeatherWS/"). This enables XPath to be used on more complex XML responses, like those returned by SOAP.
- [Virtual Attendants/XML] In Virtual Attendant scripts, a new xml_xpath_ns($xml, $prefix, $namespace) function can register a new namespace prefix on an existing $xml object returned by xml_decode(). This enables XPath to be used on more complex XML responses, like those returned by SOAP.
- [CHD-3833] [Support Center/History] Fixed an issue in the Support Center where the ticket history may not show the full results when multiple accounts are sharing their history and are recipients in common on the same tickets. The database was returning duplicate tickets in these situations, which Cerb was condensing to only distinct records. If the number of distinct results was fewer than the page limit then no additional pages were shown.
- [CHD-3834] [Platform/Requirements] Cerb now provides a more useful error message when the required 'mysqli' PHP extension isn't enabled. Previously, since 6.7.0, a blank white screen was being displayed with no additional information. The installation guides cover installing the extension but they aren't always followed (e.g. there isn't an official FreeBSD guide).
- [CHD-3830] [Reports/Localization] When running reports, the worker's current timezone is now used at the database-level. Previously, timestamps were being converted into the worker's timezone, but any relative functions in database queries (like DATE_FORMAT) were using the server's timezone. This led to report data being shifted by the worker's timezone offset.