├── LICENSE ├── README.md ├── assets ├── hashtag0.jpg ├── hashtag1.jpg ├── hashtag2.jpg ├── hashtag3.jpg ├── hashtag4.jpg └── report.jpg ├── automator ├── createTicket.php └── createTicketPeriod.php ├── hashtag ├── processTags.php ├── tag-NORMAL.php ├── tag-STATUS.php ├── tag-SUBJECT.php └── tag-WOC.php └── reports ├── report.inc.php ├── report.php ├── reportrt.php ├── viewsCreate.sql └── viewsDrop.sql /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 garyns 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # osTicket-extensions 2 | 3 | **PLEASE NOTE:** This code was written for and tested against OSTicket 1.6 and is currencly unmaintained. 4 | I have received notifications that this code does not work with OSTicket 1.10 due to schema changes. 5 | 6 | 7 | 8 | Extensions and Scripts to complement self-hosted [OSTicket.](http://www.osticket.com) They include: 9 | 10 | * Automatically schedule and create tickets. 11 | * Process #hashtags in ticket notes and comments. 12 | * Simple managerial ticket report 13 | 14 | Tested against OSTicket 1.8 15 | 16 | ## Ticket Automation 17 | 18 | In the "automation" directory are 2 php scripts for automating ticket creation. 19 | 20 | Creating a ticket from the command line: 21 | 22 | ``` 23 | ./createTicket.php subject [message] 24 | ``` 25 | 26 | Automatically scheduling ticket creation: 27 | ``` 28 | ./createTicketPeriod.php 29 | ``` 30 | This script is called from CRON to create tickets automatically on a schedule (eg daily, weekly, monthly, etc). Ticket subjects and messges are maintained in OSTicket's Knowledge-Base as an FAQ. 31 | 32 | [See here for further information and setup tutorial.](http://garysmart.com.au/osticket-automatic-scheduled-tickets/) 33 | 34 | ### Troubleshooting 35 | 36 | 37 | **Unable to create ticket with subject: [_subject_]** 38 | 39 | Ticket creation has failed. The likely cause is because the script could not reach your OSTicket API URL. Check the **$settings array** key **apiURL**. 40 | 41 | **Unable to create ticket with subject [_subject_]: Valid API key required** 42 | 43 | The script found the OSTicket API URL but failed because the provided API Key was incorrect. Check the **$settings array** key **apiKey**. Also check the API Keys page in OSTicket for the correct APIKey and IP Address. 44 | 45 | 46 | ## Simple HTML Reporting 47 | 48 | A simple HTML managerial report to report on open and closed tickets. [Here is a screen shot](assets/report.jpg). 49 | 50 | 51 | #### Background 52 | 53 | These scripts were created to provide a client with some basic managerial reporting of tickets. There are 2 scripts: 54 | 55 | **reportrt.php** *Internal* real-time reporting from the OSTicket database. Used to help manage and report tickets internally and prepair the managerial report. It reports on all tickets. 56 | 57 | **report.php** *Managerial* report for last month. It contains less information than the internal report, plus tickets from the current month are excluded. So, to generate a managerial report for August, the report is generated in September. 58 | 59 | The last comment/post in a ticket is what appears in the "Last Comment" column. The process adopted was for staff to review open tickets at the end of the month (or early in the next month), and post an internal 1 line progress comment for the report (a convention was adopted to suffix the comment with '(eom)' as seen in the the [screen shot](http://smart-itc.com.au/wp-content/uploads/2015/09/GITHubOSTicketReport.jpg)). 60 | 61 | #### Setup 62 | 63 | * The code is contained in the reports directory. This directory needs to be uploaded to your web server and made accessable via a URL. 64 | * Edit **report.inc.php** to setup database connection details. 65 | * Import the SQL in **viewsCreate.sql** into your OSTicket database. The PHP scripts use these views. Note that the SQL assumes an **ost_** prefix on tables. Edit the SQL to match your deployment. 66 | * You can add your own SQL to the report.php, etc scripts to suite your needs. 67 | 68 | #### Using 69 | * Browse to a report. Eg http://ost.yourdomain.com/reports/report.php 70 | 71 | ## Ticket #hashtags 72 | 73 | Process #hashtags in ticket notes/comments. 74 | 75 | The script **hashtag/processTags.php** processes the last thread entry for open tickets and looks for hashtags, eg "#WOC" (WOC = Wait On Client). 76 | 77 | Typically you would call this script from CRON: 78 | ``` 79 | * * * * * php /path-to-script/processTags.php > /dev/null 80 | ``` 81 | 82 | **processTags.php** then looks for an external PHP file to process the ticket. Eg, **tag-WOC.php** 83 | 84 | In the hasthag folder there are some example processing scripts: 85 | 86 | * **tag-WOC.php** update a custom OSTicket Field "TicketStatus" to read "Wait On Client". 87 | * **tag-NORMAL.php** update a custom OSTicket Field "TicketStatus" to be null. 88 | * **tag-STATUS.php** update a custom OSTicket Field "TicketStatus" to arbitrary text. 89 | * **tag-SUBJECT.php** update the ticket subject. 90 | 91 | --- 92 | **Here is tag-STATUS.php in action** 93 | 94 | **tag-STATUS.php** uses a custom ticket field called "Ticket Status", set up like this in osTicket: 95 | 96 | ![](assets/hashtag0.jpg) 97 | 98 | 99 | 1 User posts a note with #STATUS and text to a ticket. 100 | 101 | ![](assets/hashtag1.jpg) 102 | 103 | 2 After note added 104 | 105 | ![](assets/hashtag2.jpg) 106 | 107 | 3 Moments later (when processTags.php called by CRON) 108 | 109 | ![](assets/hashtag3.jpg) 110 | 111 | 4 Ticket List (*this is a customisation to show Ticket Status on the ticket list*) 112 | 113 | ![](assets/hashtag4.jpg) 114 | 115 | Note: **tag-SUBJECT.php** works similarly, excepts it updates the ticket subject field, which is a core osTicket field, not a custom field. 116 | 117 | #### Setup 118 | 119 | * Update the variable **$settings** in **processTags.php** with your database settings. 120 | * **processTags.php** needs a custom view called "tickets_last_entry". The SQL to create this view is contained in the file **reports/viewsCreate.sql** 121 | -------------------------------------------------------------------------------- /assets/hashtag0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garyns/osTicket-extensions/cc798f7a16fc90270e363be5006346665bf7075a/assets/hashtag0.jpg -------------------------------------------------------------------------------- /assets/hashtag1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garyns/osTicket-extensions/cc798f7a16fc90270e363be5006346665bf7075a/assets/hashtag1.jpg -------------------------------------------------------------------------------- /assets/hashtag2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garyns/osTicket-extensions/cc798f7a16fc90270e363be5006346665bf7075a/assets/hashtag2.jpg -------------------------------------------------------------------------------- /assets/hashtag3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garyns/osTicket-extensions/cc798f7a16fc90270e363be5006346665bf7075a/assets/hashtag3.jpg -------------------------------------------------------------------------------- /assets/hashtag4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garyns/osTicket-extensions/cc798f7a16fc90270e363be5006346665bf7075a/assets/hashtag4.jpg -------------------------------------------------------------------------------- /assets/report.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garyns/osTicket-extensions/cc798f7a16fc90270e363be5006346665bf7075a/assets/report.jpg -------------------------------------------------------------------------------- /automator/createTicket.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php -q 2 | 8, // Created tickets are assigned to this topic. 31 | 'subjectPrefix' => '[', 32 | 'subjectSuffix' => ']', 33 | 'reporterEmail' => 'automator@domain.com', 34 | 'reporterName' => 'Automator', 35 | 'apiURL' => 'http://ost.domain.com/api/http.php/tickets.json', 36 | 'apiKey' => 'your-api-key' 37 | ); 38 | 39 | if (!isset($settings)) { 40 | die ('$settings is not set. Aborting.'); 41 | } 42 | 43 | if (count($argv) === 1) { 44 | echo "\nUsage $argv[0] subject [messasge]\n\n"; 45 | exit(1); 46 | } 47 | 48 | $subject = $argv[1]; 49 | $message = isset($argv[2]) ? $argv[2] : null; 50 | 51 | createTicket($subject, $message); 52 | 53 | 54 | function createTicket($subject, $message = null) { 55 | global $settings; 56 | 57 | $topicId = $settings['topicId']; 58 | $reporterEmail = $settings['reporterEmail']; 59 | $reporterName = $settings['reporterName']; 60 | $reporterIP = gethostbyname(gethostname()); 61 | 62 | if (empty($subject)) { 63 | echo ("No Subject provided. Not creating ticket.\n"); 64 | return false; 65 | }; 66 | 67 | if (empty($message)) { 68 | $message = $subject; 69 | } 70 | 71 | $subject = $settings['subjectPrefix'] . $subject . $settings['subjectSuffix']; 72 | 73 | $data = array( 74 | 'name' => $reporterName, 75 | 'email' => $reporterEmail, 76 | 'phone' => '', 77 | 'subject' => $subject, 78 | 'message' => $message, 79 | 'ip' => $reporterIP, 80 | 'topicId' => $topicId 81 | ); 82 | 83 | function_exists('curl_version') or die('CURL support required'); 84 | function_exists('json_encode') or die('JSON support required'); 85 | 86 | set_time_limit(30); 87 | 88 | $ch = curl_init(); 89 | curl_setopt($ch, CURLOPT_URL, $settings['apiURL']); 90 | curl_setopt($ch, CURLOPT_POST, 1); 91 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); 92 | curl_setopt($ch, CURLOPT_USERAGENT, 'osTicket API Client v1.8'); 93 | curl_setopt($ch, CURLOPT_HEADER, FALSE); 94 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Expect:', 'X-API-Key: '.$settings['apiKey'])); 95 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); 96 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 97 | $result=curl_exec($ch); 98 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 99 | curl_close($ch); 100 | 101 | if ($code != 201) { 102 | echo "Unable to create ticket with subject $subject: " .$result . "\n"; 103 | return false; 104 | } 105 | 106 | $ticketId = (int)$result; 107 | 108 | echo "Ticket '$subject' created with id $ticketId\n"; 109 | 110 | return $ticketId; 111 | 112 | } // createTicket() 113 | 114 | function br2nl($string) { 115 | return preg_replace('/\/i', PHP_EOL, $string); 116 | } 117 | 118 | function decode($s) { 119 | if (empty($s)) { 120 | return $s; 121 | } 122 | 123 | $s = str_ireplace(" ", " ", $s); 124 | return trim($s); 125 | } 126 | -------------------------------------------------------------------------------- /automator/createTicketPeriod.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php -q 2 | 'localhost', 31 | 'dbTable' => 'ost.ost_faq', // Database.Table where FAQs are stored. 32 | 'dbUser' => 'root', 33 | 'dbPass' => '', 34 | 'categoryId' => 16, // The Category ID where Automator tickete FAQs are kept 35 | 'topicId' => 8, // Created tickets are assigned to this topic. 36 | 'subjectPrefix' => '[', 37 | 'subjectSuffix' => ']', 38 | 'reporterEmail' => 'automator@domain.com', 39 | 'reporterName' => 'Automator', 40 | 'apiURL' => 'http://ost.domain.com/api/http.php/tickets.json', 41 | 'apiKey' => 'your-api-key' 42 | ); 43 | 44 | if (!isset($settings)) { 45 | die ('$settings is not set. Aborting.'); 46 | } 47 | 48 | $period = isset($argv[1]) ? $argv[1] : "daily"; 49 | 50 | $tks = findTicketsToCreate($period); 51 | 52 | foreach($tks as $t) { 53 | createTicket($t->subject, $t->message); 54 | } 55 | 56 | 57 | 58 | // $period to match FAQ Question field. 59 | function findTicketsToCreate($period = "daily") { 60 | global $settings; 61 | 62 | $link = mysql_connect($settings['dbHost'], $settings['dbUser'], $settings['dbPass']); 63 | 64 | if (!$link) { 65 | die('Could not connect: ' . mysql_error()); 66 | } 67 | 68 | $sql_query = "select faq_id, answer from " . $settings['dbTable'] . " WHERE category_id=" . $settings['categoryId'] . " AND UPPER(question) LIKE UPPER('%$period%')"; 69 | 70 | $sql_result = mysql_query($sql_query, $link); 71 | 72 | $rowsFound = false; 73 | $results = array(); 74 | 75 | while ($row = mysql_fetch_array($sql_result,MYSQL_ASSOC)) { 76 | $rowsFound = true; 77 | 78 | $lines = explode("\n", trim(br2nl($row['answer']))) ; 79 | 80 | foreach($lines as $line) { 81 | 82 | $line = trim($line); 83 | 84 | // Skip empty lines or lines starting with a comment (-- or #) 85 | if (empty($line) || (strpos($line, "--") === 0) || (strpos($line, "#") === 0)) { 86 | continue; 87 | } 88 | 89 | $subject = $line; 90 | $message = null; 91 | 92 | if (strpos($line, "|") !== FALSE) { 93 | list($subject, $message) = explode("|", $line); 94 | } 95 | 96 | $subject = decode($subject); 97 | $message = decode($message); 98 | 99 | if (empty($message)) { 100 | $message = $subject; 101 | } 102 | 103 | $tmp = new stdClass(); 104 | $tmp->faqId = $row['faq_id']; 105 | $tmp->subject = $subject; 106 | $tmp->message = $message . "\n\nPeriod: $period"; 107 | $results[] = $tmp; 108 | } 109 | } 110 | 111 | mysql_free_result($sql_result); 112 | mysql_close($link); 113 | 114 | if (!$rowsFound) { 115 | $msg = "Automator called for Period '$period' but found no tickets to create"; 116 | echo $msg . "\n"; 117 | createTicket($msg); 118 | } 119 | 120 | return $results; 121 | } // findTicketsToCreate() 122 | 123 | 124 | function createTicket($subject, $message = null) { 125 | global $settings; 126 | 127 | $topicId = $settings['topicId']; 128 | $reporterEmail = $settings['reporterEmail']; 129 | $reporterName = $settings['reporterName']; 130 | $reporterIP = gethostbyname(gethostname()); 131 | 132 | if (empty($subject)) { 133 | echo ("No Subject provided. Not creating ticket.\n"); 134 | return false; 135 | }; 136 | 137 | if (empty($message)) { 138 | $message = $subject; 139 | } 140 | 141 | $subject = $settings['subjectPrefix'] . $subject . $settings['subjectSuffix']; 142 | 143 | $data = array( 144 | 'name' => $reporterName, 145 | 'email' => $reporterEmail, 146 | 'phone' => '', 147 | 'subject' => $subject, 148 | 'message' => $message, 149 | 'ip' => $reporterIP, 150 | 'topicId' => $topicId 151 | ); 152 | 153 | function_exists('curl_version') or die('CURL support required'); 154 | function_exists('json_encode') or die('JSON support required'); 155 | 156 | set_time_limit(30); 157 | 158 | $ch = curl_init(); 159 | curl_setopt($ch, CURLOPT_URL, $settings['apiURL']); 160 | curl_setopt($ch, CURLOPT_POST, 1); 161 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); 162 | curl_setopt($ch, CURLOPT_USERAGENT, 'osTicket API Client v1.8'); 163 | curl_setopt($ch, CURLOPT_HEADER, FALSE); 164 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Expect:', 'X-API-Key: '.$settings['apiKey'])); 165 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); 166 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 167 | $result=curl_exec($ch); 168 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 169 | curl_close($ch); 170 | 171 | if ($code != 201) { 172 | echo "Unable to create ticket with subject $subject: " .$result . "\n"; 173 | return false; 174 | } 175 | 176 | $ticketId = (int)$result; 177 | 178 | echo "Ticket '$subject' created with id $ticketId\n"; 179 | 180 | return $ticketId; 181 | 182 | } // createTicket() 183 | 184 | function br2nl($string) { 185 | return preg_replace('/\/i', PHP_EOL, $string); 186 | } 187 | 188 | function decode($s) { 189 | if (empty($s)) { 190 | return $s; 191 | } 192 | 193 | $s = str_ireplace(" ", " ", $s); 194 | return trim($s); 195 | } 196 | -------------------------------------------------------------------------------- /hashtag/processTags.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php -q 2 | 'localhost', 33 | 'dbUser' => 'root', 34 | 'dbPass' => '', 35 | 'dbDatabase' => 'ost', 36 | 'dbTablePrefix' => 'ost_' 37 | ); 38 | 39 | error_reporting(E_ALL); 40 | ini_set('display_errors', 1); 41 | 42 | // Connect to localhost @ port 3306 43 | $link = mysql_connect($settings['dbHost'], $settings['dbUser'], $settings['dbPass']); 44 | if (!$link) { 45 | die('Could not connect: ' . mysql_error()); 46 | } 47 | 48 | // Select database 49 | $db = mysql_select_db($settings['dbDatabase'], $link); 50 | 51 | if (!$db) { 52 | die('Could not open database: ' . mysql_error()); 53 | } 54 | 55 | $sql_query = "SELECT ticket_id, thread_id, body FROM tickets_last_entry WHERE status='open' AND UPPER(body) LIKE UPPER('%#%');"; 56 | 57 | $sql_result = mysql_query($sql_query, $link); 58 | 59 | if (($sql_result)||(mysql_errno == 0)) { 60 | 61 | while ($row = mysql_fetch_array($sql_result,MYSQL_ASSOC)) { 62 | 63 | $ticketId = $row['ticket_id']; 64 | $threadId = $row['thread_id']; 65 | $body = $row['body']; 66 | $hashtags = get_hash_tags($row['body']); 67 | 68 | if (count($hashtags) > 0) { 69 | 70 | echo "Ticket $ticketId: #" . implode(",#", $hashtags) . "\n"; 71 | 72 | foreach($hashtags as $hashtag) { 73 | process_hash_tag($ticketId, $threadId, $body, $hashtag); 74 | } 75 | } 76 | 77 | } // white 78 | 79 | mysql_free_result($sql_result); 80 | } // if result 81 | 82 | function get_hash_tags($text) { 83 | $tags = array(); 84 | 85 | preg_match_all('/(^|[^a-z0-9_])#([a-z0-9_]+)/i', $text, $matches); 86 | $hashtag = ''; 87 | 88 | if (!empty($matches[0])) { 89 | foreach($matches[0] as $match) { 90 | 91 | $hashtag = trim(preg_replace("/[^a-z0-9]+/i", "", $match)); 92 | 93 | $isColor = preg_match('/#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\b/', $match); 94 | 95 | if ($isColor || is_numeric($hashtag) || empty($hashtag)) { 96 | // Skip certain hashtags what we find in HTML tickets. 97 | continue; 98 | } 99 | 100 | $tags[] = $hashtag; 101 | } 102 | } 103 | 104 | return $tags; 105 | } 106 | 107 | 108 | /** 109 | * Find hashtags in $body. 110 | * @return Array of tags found (without # prefixed); 111 | */ 112 | function process_hash_tag($ticketId, $threadId, $body, $hashtag) { 113 | global $link; 114 | 115 | echo "Ticket $ticketId #$hashtag: "; 116 | 117 | $dir = dirname(__FILE__); 118 | $file = "$dir/tag-" . strToUpper($hashtag) . ".php"; 119 | 120 | // body2 is body with the hasttag removed and all html tags removed. 121 | $body2 = trim(strip_tags(str_ireplace("#$hashtag", "", $body))); 122 | 123 | if (file_exists("$file")) { 124 | ob_start(); 125 | include "$file"; 126 | $t = ob_get_clean(); 127 | echo $t; 128 | } else { 129 | echo "No processing file $file found."; 130 | } 131 | 132 | echo "\n"; 133 | } 134 | 135 | /** 136 | * Add a new internal note to a ticket. 137 | */ 138 | function post_ticket_note($ticketId, $note) { 139 | global $link, $settings; 140 | 141 | $sql = "INSERT INTO " . $settings['dbTablePrefix'] . "ticket_thread (ticket_id, pid, staff_id, user_id, thread_type, source, title, body, format, ip_address, created, updated) VALUES ($ticketId, 0, 0, 0, 'N', 'TagProcessor', NULL, '" . mysql_escape_string(nl2br($note)) . "', 'html', '', NOW(), NOW());"; 142 | 143 | $result = mysql_query($sql, $link); 144 | 145 | if ($result === FALSE) { 146 | echo "Ticket $ticketId ERROR posting note '$note': " . mysql_error($link) . "\n"; 147 | return false; 148 | } 149 | 150 | return true; 151 | } 152 | 153 | /** 154 | * Replace the body text on an existing ticket thread. 155 | */ 156 | function update_thread($ticketId, $threadId, $note) { 157 | global $link, $settings; 158 | 159 | $sql = "UPDATE " . $settings['dbTablePrefix'] . "ticket_thread SET body='" . mysql_escape_string(nl2br($note)) . "', updated=NOW() WHERE id=$threadId;"; 160 | 161 | $result = mysql_query($sql, $link); 162 | 163 | if ($result === FALSE) { 164 | echo "Ticket $ticketId ERROR Updating Thread $threadId '$note': " . mysql_error($link) . "\n"; 165 | return false; 166 | } 167 | 168 | return true; 169 | 170 | } 171 | -------------------------------------------------------------------------------- /hashtag/tag-NORMAL.php: -------------------------------------------------------------------------------- 1 | $hashtag TicketStatus Reset.", $body); 11 | echo $result ? "OK" : "ERROR: " . mysql_error($link); 12 | 13 | update_thread($ticketId, $threadId, $newBody); 14 | -------------------------------------------------------------------------------- /hashtag/tag-STATUS.php: -------------------------------------------------------------------------------- 1 | $hashtag\nTicketStatus Now '$body2'"); 12 | -------------------------------------------------------------------------------- /hashtag/tag-SUBJECT.php: -------------------------------------------------------------------------------- 1 | $hashtag\nStatus Updated '$body2'"); 10 | -------------------------------------------------------------------------------- /hashtag/tag-WOC.php: -------------------------------------------------------------------------------- 1 | $hashtag TicketStatus Now 'Wait On Client'", $body); 11 | echo $result ? "OK" : "ERROR: " . mysql_error($link); 12 | 13 | update_thread($ticketId, $threadId, $newBody); 14 | -------------------------------------------------------------------------------- /reports/report.inc.php: -------------------------------------------------------------------------------- 1 | 'localhost', 30 | 'dbUser' => 'root', 31 | 'dbPass' => '', 32 | 'dbDatabase' => 'ost' 33 | ); 34 | 35 | 36 | error_reporting(E_ALL); 37 | ini_set('display_errors', 1); 38 | 39 | // Connect to localhost @ port 3306 40 | $link = mysql_connect($settings['dbHost'], $settings['dbUser'], $settings['dbPass']); 41 | if (!$link) { 42 | die('Could not connect: ' . mysql_error()); 43 | } 44 | 45 | linebreak(); 46 | 47 | // Select database 48 | $db = mysql_select_db($settings['dbDatabase'], $link); 49 | 50 | if (!$db) { 51 | die('Could not open database: ' . mysql_error()); 52 | } 53 | 54 | /** 55 | * Wraps text with HTML tag STRONG. 56 | */ 57 | function strong($text) { 58 | return "$text\n"; 59 | } 60 | 61 | /** 62 | * Ends text with HTML tag BR. 63 | * Default return just BR. 64 | */ 65 | function linebreak($text="\n") { 66 | echo nl2br( $text ); 67 | } 68 | 69 | /** 70 | * Create a dynamic table with headers based on the column names 71 | * from a query. It automatically creates the table and the correct 72 | * number of columns. 73 | */ 74 | function createDynamicHTMLTable($table_name, $sql_query) { 75 | global $link; 76 | $counter=0; 77 | 78 | // execute SQL query and get result 79 | $sql_result = mysql_query($sql_query, $link); 80 | if (($sql_result)||(mysql_errno == 0)) { 81 | echo "
\n"; 82 | linebreak( strong( sprintf("%s", $table_name) ) ); 83 | echo "\n"; 84 | echo "\n"; 85 | if (mysql_num_rows($sql_result)>0) 86 | { 87 | //loop thru the field names to print the correct headers 88 | $i = 0; 89 | echo "\n"; 90 | echo "\n"; 91 | 92 | while ($i < mysql_num_fields($sql_result)) 93 | { 94 | echo "\n"; 95 | $i++; 96 | } 97 | echo "\n"; 98 | 99 | 100 | //display The data 101 | while ($rows = mysql_fetch_array($sql_result,MYSQL_ASSOC)) { 102 | echo "\n"; 103 | echo ""; 104 | 105 | foreach ($rows as $data) 106 | { 107 | 108 | $align = (is_numeric($data)) ? "center": "left"; 109 | echo "\n"; 110 | } 111 | echo "\n"; 112 | } 113 | } else { 114 | echo "\n\n"; 115 | } 116 | 117 | echo "\n
#". mysql_field_name($sql_result, $i) . "
". ++$counter ."". $data . "
No Results found!
\n"; 118 | echo "
\n"; 119 | } else { 120 | echo nl2br( sprintf( "Error in running query: %s\n", mysql_error()) ); 121 | } 122 | 123 | mysql_free_result($sql_result); 124 | 125 | linebreak(); 126 | } 127 | 128 | 129 | -------------------------------------------------------------------------------- /reports/report.php: -------------------------------------------------------------------------------- 1 |