diff --git a/README.md b/README.md index 9d9c492..e84c18f 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# Smile Menu +## Smile Menu 0.0.1 ALPHA + +A plugin for MyBB 1.8.x that adds autocomplete for smilies \ No newline at end of file diff --git a/Upload/admin/styles/default/images/sm/donate.gif b/Upload/admin/styles/default/images/sm/donate.gif new file mode 100644 index 0000000..43cef69 Binary files /dev/null and b/Upload/admin/styles/default/images/sm/donate.gif differ diff --git a/Upload/admin/styles/default/images/sm/logo.png b/Upload/admin/styles/default/images/sm/logo.png new file mode 100644 index 0000000..e08333b Binary files /dev/null and b/Upload/admin/styles/default/images/sm/logo.png differ diff --git a/Upload/admin/styles/default/images/sm/settings.gif b/Upload/admin/styles/default/images/sm/settings.gif new file mode 100644 index 0000000..f0724ed Binary files /dev/null and b/Upload/admin/styles/default/images/sm/settings.gif differ diff --git a/Upload/inc/languages/english/admin/sm.lang.php b/Upload/inc/languages/english/admin/sm.lang.php new file mode 100644 index 0000000..04ef15b --- /dev/null +++ b/Upload/inc/languages/english/admin/sm.lang.php @@ -0,0 +1,36 @@ + diff --git a/Upload/inc/languages/english/sm.lang.php b/Upload/inc/languages/english/sm.lang.php new file mode 100644 index 0000000..92f1330 --- /dev/null +++ b/Upload/inc/languages/english/sm.lang.php @@ -0,0 +1,15 @@ + diff --git a/Upload/inc/plugins/sm.php b/Upload/inc/plugins/sm.php new file mode 100644 index 0000000..f6f0830 --- /dev/null +++ b/Upload/inc/plugins/sm.php @@ -0,0 +1,45 @@ +
Please make sure IN_MYBB is defined.'); +} + +// checked by other plugin files +define('SMILEMENU_VERSION', '0.0.1'); + +// register custom class autoloader +spl_autoload_register('smClassAutoLoad'); + +// load install routines only if in ACP +if (defined('IN_ADMINCP')) { + global $mybb; + if ($mybb->input['module'] == 'config-plugins' || + $mybb->input['module'] == 'config-settings') { + require_once MYBB_ROOT . 'inc/plugins/sm/install.php'; + } +} else { + require_once MYBB_ROOT . 'inc/plugins/sm/forum.php'; +} + +/** + * class autoloader + * + * @param string the name of the class to load + */ +function smClassAutoLoad($className) { + $path = MYBB_ROOT . "inc/plugins/sm/classes/{$className}.php"; + + if (file_exists($path)) { + require_once $path; + } +} + +?> diff --git a/Upload/inc/plugins/sm/classes/SmileMenuCache.php b/Upload/inc/plugins/sm/classes/SmileMenuCache.php new file mode 100644 index 0000000..2fdb4e9 --- /dev/null +++ b/Upload/inc/plugins/sm/classes/SmileMenuCache.php @@ -0,0 +1,37 @@ + diff --git a/Upload/inc/plugins/sm/classes/SmileMenuInstaller.php b/Upload/inc/plugins/sm/classes/SmileMenuInstaller.php new file mode 100644 index 0000000..60db5e9 --- /dev/null +++ b/Upload/inc/plugins/sm/classes/SmileMenuInstaller.php @@ -0,0 +1,35 @@ + diff --git a/Upload/inc/plugins/sm/classes/WildcardPluginCache010300.php b/Upload/inc/plugins/sm/classes/WildcardPluginCache010300.php new file mode 100644 index 0000000..a7484a1 --- /dev/null +++ b/Upload/inc/plugins/sm/classes/WildcardPluginCache010300.php @@ -0,0 +1,159 @@ +cacheData = $cache->read($this->cacheKey); + } + + /** + * retrieve an individual cache entry + * + * @param string the name of the entry + * @return bool + */ + public function read($key = null) + { + if ($key === null) { + if ($this->subKey) { + return $this->cacheData[$this->subKey]; + } + return $this->cacheData; + } + + if ($this->subKey && + isset($this->cacheData[$this->subKey][$key])) { + return $this->cacheData[$this->subKey][$key]; + } elseif (isset($this->cacheData[$key])) { + return $this->cacheData[$key]; + } + return false; + } + + /** + * update the value of a single cache entry + * + * @param string the name of the entry + * @param mixed the value of the entry + * @param bool true to save immediately or + * false (default) to wait till shut down + * @param bool true (default) to update the + * entire cache in the db + * @return void + */ + public function update($key = null, $val, $hard = false) + { + if ($key === null) { + if ($this->subKey) { + $this->cacheData[$this->subKey] = $val; + } else { + $this->cacheData = $val; + } + } else { + if ($this->subKey) { + $this->cacheData[$this->subKey][$key] = $val; + } else { + $this->cacheData[$key] = $val; + } + } + $this->hasChanged($hard); + } + + /** + * save the entire cache to the db + * + * @return void + */ + public function save() + { + global $cache; + $cache->update($this->cacheKey, $this->cacheData); + } + + /** + * clear the entire cache + * + * @param bool true to clear and save immediately or + * false (default) to wait till shut down + * @return void + */ + public function clear($hard = false) + { + if ($this->subKey) { + $this->cacheData[$this->subKey] = null; + } else { + $this->cacheData = null; + } + $this->hasChanged($hard); + } + + /** + * mark the cache as in need of saving if shut + * down functionality is enabled, or save immediately + * if not + * + * @param bool true to clear and save immediately or + * false (default) to wait till shut down + * @return void + */ + protected function hasChanged($hard = false) + { + global $mybb; + if ($hard || + !$mybb->use_shutdown) { + $this->save(); + return; + } + + add_shutdown(array($this, 'save')); + } + + /** + * get the cached version + * + * @return string|int + */ + public function getVersion() + { + $version = trim($this->read('version')); + if (!$version) { + $version = 0; + } + return $version; + } + + /** + * set the cached version + * + * @param string + * @return string|int + */ + public function setVersion($version) + { + $this->update('version', trim($version)); + } +} + +?> diff --git a/Upload/inc/plugins/sm/classes/WildcardPluginCacheInterface010200.php b/Upload/inc/plugins/sm/classes/WildcardPluginCacheInterface010200.php new file mode 100644 index 0000000..c4fbb8d --- /dev/null +++ b/Upload/inc/plugins/sm/classes/WildcardPluginCacheInterface010200.php @@ -0,0 +1,20 @@ + diff --git a/Upload/inc/plugins/sm/classes/WildcardPluginInstaller020001.php b/Upload/inc/plugins/sm/classes/WildcardPluginInstaller020001.php new file mode 100644 index 0000000..4807f1e --- /dev/null +++ b/Upload/inc/plugins/sm/classes/WildcardPluginInstaller020001.php @@ -0,0 +1,941 @@ +$key = $$key; + } + + if (!empty($styleSheets)) { + foreach (array('acp', 'forum') as $key) { + if (!is_array($styleSheets[$key]) || + empty($styleSheets[$key])) { + $this->styleSheetNames[$key] = array(); + continue; + } + + foreach (array_keys($styleSheets[$key]) as $name) { + // stylesheets need the extension appended + $this->styleSheetNames[$key][] = $name . '.css'; + } + } + } + + // settings and templates and their groups are handled similarly + if (!empty($settings)) { + $this->settingGroupNames = array_keys($settings); + foreach ($settings as $group => $info) { + foreach ($info['settings'] as $name => $setting) { + $this->settingNames[] = $name; + } + } + } + + if (!empty($templates)) { + $this->templategroupNames = array_keys($templates); + foreach ($templates as $group => $info) { + foreach ($info['templates'] as $name => $template) { + $this->templateNames[] = $name; + } + } + } + + // tables and columns must consider the different db engines + if (!empty($tables)) { + if ($db->engine == 'pgsql') { + $this->tables = $tables['pgsql']; + } else { + unset($this->tables['pgsql']); + } + $this->tableNames = array_keys($this->tables); + } + + if (!empty($columns)) { + if ($db->engine == 'pgsql') { + $this->columns = $columns['pgsql']; + } else { + unset($this->columns['pgsql']); + } + $this->columnNames = array_keys($this->columns); + } + + // snag a copy of the db object + $this->db = $db; + } + + /** + * install all the elements stored in the installation data file + * + * @return void + */ + public function install() + { + $this->addTables(); + $this->addColumns(); + $this->addSettings(); + $this->addTemplates(); + $this->addStyleSheets(); + $this->addImages(); + } + + /** + * uninstall all elements as provided in the install data + * + * @return void + */ + public function uninstall() + { + $this->removeTables(); + $this->removeColumns(); + $this->remove('settinggroups', 'name', $this->settingGroupNames); + $this->remove('settings', 'name', $this->settingNames); + $this->remove('templategroups', 'prefix', $this->templategroupNames); + $this->remove('templates', 'title', $this->templateNames); + $this->removeStyleSheets(); + rebuild_settings(); + } + + /** + * create a correctly collated table from an array of options + * + * @param string table name without prefix + * @param array the columns + * @return void + */ + protected function addTable($table, $columns) + { + static $collation; + if (!isset($collation) || + strlen($collation) == 0) { + // only build collation for the first table + $collation = $this->db->build_create_table_collation(); + } + + // build the column list + $sep = $columnList = ''; + foreach ($columns as $title => $definition) { + $columnList .= "{$sep}{$title} {$definition}"; + $sep = ','; + } + + // create the table if it doesn't already exist + if (!$this->tableExists($table)) { + $queryExtra = ($this->db->engine == 'pgsql') ? '' : " ENGINE={$this->db->table_type}{$collation}"; + $this->db->write_query("CREATE TABLE {$this->db->table_prefix}{$table} ({$columnList}){$queryExtra};"); + } + } + + /** + * create multiple tables from stored info + * + * @param array database tables and their columns + * @return void + */ + protected function addTables() + { + if (!is_array($this->tables) || + empty($this->tables)) { + return false; + } + + foreach ($this->tables as $table => $columns) { + if ($this->tableExists($table)) { + // if it already exists, just check that all the columns are present (and add them if not) + $this->addColumns(array($table => $columns)); + } else { + $this->addTable($table, $columns); + } + } + } + + /** + * drop multiple database tables + * + * @return void + */ + protected function removeTables() + { + if (!is_array($this->tableNames) || + empty($this->tableNames)) { + return; + } + + foreach ($this->tableNames as $table) { + $this->db->drop_table($table); + } + } + + /** + * add columns in the list to a table (if they do not already exist) + * + * @param array tables and columns + * @return void + */ + protected function addColumns($columns='') + { + if (!is_array($columns) || + empty($columns)) { + $columns = $this->columns; + } + + foreach ($columns as $table => $allColumns) { + foreach ($allColumns as $title => $definition) { + if (!$this->fieldExists($table, $title)) { + $this->db->add_column($table, $title, $definition); + } + } + } + } + + /** + * drop multiple listed columns + * + * @param array tables and columns + * @return void + */ + protected function removeColumns() + { + if (!is_array($this->columns) || + empty($this->columns)) { + return; + } + + foreach ($this->columns as $table => $columns) { + foreach ($columns as $title => $definition) { + if ($this->fieldExists($table, $title)) { + $this->db->drop_column($table, $title); + } + } + } + } + + /** + * create multiple setting groups + * + * @param array setting groups + * @return array setting groups and gids + */ + protected function addSettingGroups($groups) + { + if (!is_array($groups) || + empty($groups)) { + return false; + } + + $insertArray = $gids = array(); + foreach ($groups as $name => $group) { + $query = $this->db->simple_select('settinggroups', 'gid', "name='{$name}'"); + if ($this->db->num_rows($query) > 0) { + $group['gid'] = (int) $this->db->fetch_field($query, 'gid'); + $gids[$name] = $group['gid']; + $this->db->update_query('settinggroups', $group, "name='{$name}'"); + } else { + $gid = $this->db->insert_query('settinggroups', $group); + $gids[$name] = $gid; + } + } + return $gids; + } + + /** + * create settings from an array + * + * @param array groups and settings + * @return void + */ + protected function addSettings() + { + if (!is_array($this->settings) || + empty($this->settings)) { + return; + } + + foreach ($this->settings as $group => $data) { + $gids = $this->addSettingGroups(array($group => $data['group'])); + $gid = $gids[$group]; + + $insertArray = array(); + foreach ($data['settings'] as $name => $setting) { + $setting['gid'] = $gid; + // does the setting already exist? + $query = $this->db->simple_select('settings', 'sid', "name='{$name}'"); + if ($this->db->num_rows($query) > 0) { + $setting['sid'] = (int) $this->db->fetch_field($query, 'sid'); + + // update the info (but leave the value alone) + unset($setting['value']); + $this->db->update_query('settings', $setting, "name='{$name}'"); + } else { + $insertArray[] = $setting; + } + } + if (!empty($insertArray)) { + $this->db->insert_query_multiple('settings', $insertArray); + } + } + rebuild_settings(); + } + + /** + * create or update the template groups stored in the object + * + * @return void + */ + protected function addTemplateGroups() + { + if (!is_array($this->templates) || + empty($this->templates)) { + return; + } + + $insertArray = $update_array = array(); + + foreach ($this->templates as $prefix => $data) { + $query = $this->db->simple_select('templategroups', 'gid', "prefix='{$prefix}'"); + if ($this->db->num_rows($query) > 0) { + $gid = (int) $this->db->fetch_field($query, 'gid'); + $this->db->update_query('templategroups', $data['group'], "gid='{$gid}'"); + } else { + $insertArray[] = $data['group']; + } + } + + if (!empty($insertArray)) { + $this->db->insert_query_multiple('templategroups', $insertArray); + } + } + + /** + * create multiple templates from stored info + * + * @return void + */ + protected function addTemplates() + { + if (!is_array($this->templates) || + empty($this->templates)) { + return; + } + + $this->addTemplateGroups(); + + $insertArray = array(); + foreach ($this->templates as $group => $data) { + foreach ($data['templates'] as $title => $template) { + $title = $this->db->escape_string($title); + $template = $this->db->escape_string($template); + $templateArray = array( + "title" => $title, + "template" => $template, + "sid" => -2, + "version" => 1, + "dateline" => TIME_NOW, + ); + + $query = $this->db->simple_select('templates', 'tid', "title='{$title}' AND sid IN('-2', '-1')"); + if ($this->db->num_rows($query) > 0) { + $tid = (int) $this->db->fetch_field($query, 'tid'); + $this->db->update_query('templates', $templateArray, "tid='{$tid}'"); + } else { + $insertArray[] = $templateArray; + } + } + } + + if (!empty($insertArray)) { + $this->db->insert_query_multiple('templates', $insertArray); + } + } + + /** + * add any listed style sheets + * + * @return void + */ + protected function addStyleSheets() + { + if (!is_array($this->styleSheets) || + empty($this->styleSheets) || + (empty($this->styleSheets['acp']) && + empty($this->styleSheets['forum']))) { + return; + } + + global $config; + + if (!empty($this->styleSheets['acp'])) { + // if there is a sub-folder for images, make sure it starts with a slash + $mainFolder = $this->styleSheets['folder']; + if ($mainFolder && + !substr($mainFolder, 1, 1) !== '/') { + $mainFolder = "/{$mainFolder}"; + } + + foreach ($this->buildThemeList(true) as $folder) { + // set up a path and make sure we can write to it + $path = MYBB_ADMIN_DIR . "styles/{$folder}"; + + if ($mainFolder && + !is_dir("{$path}{$mainFolder}") && + !mkdir("{$path}{$mainFolder}", 0777, true)) { + continue; + } + + foreach ($this->styleSheets['acp'] as $filename => $details) { + // if there is a sub-folder make sure it has a trailing slash + if ($details['folder'] && + substr($details['folder'], strlen($details['folder']) - 1, 1) != '/') { + $details['folder'] .= '/'; + } + + $fullPath = "{$path}{$mainFolder}/{$details['folder']}{$filename}.css"; + file_put_contents($fullPath, $details['stylesheet']); + } + } + } + + if (empty($this->styleSheets['forum'])) { + return; + } + + foreach ($this->styleSheets['forum'] as $name => $data) { + $attachedto = $data['attachedto']; + if (is_array($data['attachedto'])) { + $attachedto = array(); + foreach ($data['attachedto'] as $file => $actions) { + if (is_array($actions)) { + $actions = implode(",", $actions); + } + + if ($actions) { + $file = "{$file}?{$actions}"; + } + $attachedto[] = $file; + } + $attachedto = implode("|", $attachedto); + } + + $name = $this->db->escape_string($name) . '.css'; + $styleSheet = array( + 'name' => $name, + 'tid' => 1, + 'attachedto' => $this->db->escape_string($attachedto), + 'stylesheet' => $this->db->escape_string($data['stylesheet']), + 'cachefile' => $name, + 'lastmodified' => TIME_NOW, + ); + + // update any children + $this->db->update_query('themestylesheets', array( + "attachedto" => $styleSheet['attachedto'] + ), "name='{$name}'"); + + // now update/insert the master stylesheet + $query = $this->db->simple_select('themestylesheets', 'sid', "tid='1' AND name='{$name}'"); + $sid = (int) $this->db->fetch_field($query, 'sid'); + + if ($sid) { + $this->db->update_query('themestylesheets', $styleSheet, "sid='{$sid}'"); + } else { + $sid = $this->db->insert_query('themestylesheets', $styleSheet); + $styleSheet['sid'] = (int) $sid; + } + + // now cache the actual files + require_once MYBB_ROOT . "{$config['admin_dir']}/inc/functions_themes.php"; + + if(!cache_stylesheet(1, $styleSheet['cachefile'], $data['stylesheet'])) + { + $this->db->update_query("themestylesheets", array('cachefile' => "css.php?stylesheet={$sid}"), "sid='{$sid}'", 1); + } + + // and update the CSS file list + update_theme_stylesheet_list(1, false, true); + } + } + + /** + * completely remove any style sheets in install_data.php + * + * @return void + */ + protected function removeStyleSheets() + { + if (empty($this->styleSheetNames) || + !is_array($this->styleSheetNames) || + (empty($this->styleSheets['acp']) && + empty($this->styleSheets['forum']))) { + return; + } + + if (!empty($this->styleSheets['acp'])) { + // if there is a sub-folder for images, make sure it starts with a slash + $mainFolder = $this->styleSheets['folder']; + if ($mainFolder && + !substr($mainFolder, 1, 1) !== '/') { + $mainFolder = "/{$mainFolder}"; + } + + foreach ($this->buildThemeList(true) as $folder) { + // set up a path and make sure we can write to it + $path = MYBB_ADMIN_DIR . "styles/{$folder}"; + + if ($mainFolder && + !is_dir("{$path}{$mainFolder}")) { + continue; + } + + foreach ($this->styleSheetNames['acp'] as $filename) { + // if there is a sub-folder make sure it has a trailing slash + if ($details['folder'] && + substr($details['folder'], strlen($details['folder']) - 1, 1) != '/') { + $details['folder'] .= '/'; + } + + @unlink(MYBB_ADMIN_DIR . "styles/{$folder}{$mainFolder}/{$details['folder']}{$filename}"); + } + } + } + + if (empty($this->styleSheets['forum'])) { + return; + } + + // get a list and form the WHERE clause + $styleSheetList = "'" . implode("','", $this->styleSheetNames['forum']) . "'"; + $where = "name={$styleSheetList}"; + if (count($this->styleSheetNames['forum']) > 1) { + $where = "name IN({$styleSheetList})"; + } + + // find the master and any children + $query = $this->db->simple_select('themestylesheets', 'tid,name', $where); + + // delete them all from the server + while ($styleSheet = $this->db->fetch_array($query)) { + @unlink(MYBB_ROOT."cache/themes/{$styleSheet['tid']}_{$styleSheet['name']}"); + @unlink(MYBB_ROOT."cache/themes/theme{$styleSheet['tid']}/{$styleSheet['name']}"); + } + + // then delete them from the database + $this->db->delete_query('themestylesheets', $where); + + // now remove them from the CSS file list + require_once MYBB_ADMIN_DIR . "inc/functions_themes.php"; + update_theme_stylesheet_list(1, false, true); + } + + /** + * copy default images to each theme + * + * @return void + */ + protected function addImages() + { + if (!is_array($this->images) || + empty($this->images) || + (!$this->images['forum'] && !$this->images['acp'])) { + return; + } + + // if there is a sub-folder for images, make sure it has a trailing slash + $mainFolder = $this->images['folder']; + if ($mainFolder && + !substr($mainFolder, 1, 1) !== '/') { + $mainFolder = "/{$mainFolder}"; + } + + // handle ACP images + if (is_array($this->images['acp'])) { + // load all detected themes + foreach ($this->buildThemeList(true) as $foldername) { + // set up a path and make sure we can write to it + $path = MYBB_ADMIN_DIR . "styles/{$foldername}"; + + if ((!is_dir("{$path}/images") && + !mkdir("{$path}/images", 0777, true)) || + ($mainFolder && + !is_dir("{$path}/images{$mainFolder}") && + !$this->createContentFolder("{$path}/images{$mainFolder}"))) { + continue; + } + + foreach ($this->images['acp'] as $filename => $details) { + // if there is a sub-folder make sure it has a trailing slash + if ($details['folder'] && + substr($details['folder'], strlen($details['folder']) - 1, 1) != '/') { + $details['folder'] .= '/'; + } + + // don't overwrite or upgrades will kill custom images + $fullPath = MYBB_ADMIN_DIR . "styles/{$foldername}/images{$mainFolder}/{$details['folder']}{$filename}"; + if (!file_exists($fullPath)) { + file_put_contents($fullPath, base64_decode($details['image'])); + } + } + } + } + + // handle the forum side images if any + if (is_array($this->images['forum'])) { + global $mybb; + + foreach ($this->buildThemeList() as $dir) { + // make sure our folders exist + $path = MYBB_ROOT . $dir; + if (!is_dir($path) || + ($mainFolder && + !is_dir("{$path}{$mainFolder}") && + !$this->createContentFolder("{$path}{$mainFolder}"))) { + continue; + } + + foreach ($this->images['forum'] as $filename => $details) { + // if this attribute is set, install the images in language directory + if ($details['lang']) { + $fullPath = "{$path}/{$mybb->settings['bblanguage']}/{$filename}"; + } else { + // if there is a sub-folder ensure that it has a trailing slash + if ($details['folder'] && + substr($details['folder'], strlen($details['folder']) - 1, 1) != '/') { + $details['folder'] .= '/'; + } + $fullPath = "{$path}{$mainFolder}/{$details['folder']}{$filename}"; + } + + // don't overwrite or upgrades will kill custom images + if (!file_exists($fullPath)) { + file_put_contents($fullPath, base64_decode($details['image'])); + } + } + } + } + } + + /** + * removed rows from a named table when values of the + * named column are matched with members of the list + * + * @param string table name without prefix + * @param string field name + * @param array string values + * @return void + */ + protected function remove($table, $field, $list) + { + if (!is_array($list)) { + $list = array($list); + } + + if (empty($list)) { + return; + } + + if ($this->tableExists($table) && + $this->fieldExists($table, $field)) { + $delete_list = "'" . implode("','", $list) . "'"; + $this->db->delete_query($table, "{$field} IN ({$delete_list})"); + } + } + + /** + * verify the existence of named table + * + * @param string table name without prefix + * @return bool true if it exists, false if not + */ + protected function tableExists($table) + { + static $tableList; + + if (!isset($tableList)) { + $tableList = $this->buildTableList(); + } + return isset($tableList[$this->db->table_prefix . $table]); + } + + /** + * build an array of all the tables in the current database + * + * @return array keys for the table names and 1 for the values + */ + protected function buildTableList() + { + global $config; + + // PostgreSQL requires a little more work to grab the table names + if ($this->db->engine == 'pgsql') { + $tableArray = $this->db->list_tables($config['database']['database'], $this->db->table_prefix); + + foreach ($tableArray as $table) { + $tableList[$table] = 1; + } + } else { + $query = $this->db->write_query(" + SHOW TABLES + FROM `{$config['database']['database']}` + "); + + $tableList = array(); + while ($row = $this->db->fetch_array($query)) { + $tableList[array_pop($row)] = 1; + } + } + return $tableList; + } + + /** + * verify the existence of the named column of the named table + * + * @param string table name without prefix + * @param string field name + * @return bool true if it exists/false if not + */ + protected function fieldExists($table, $field) + { + static $fieldList; + + if (!isset($fieldList[$table])) { + $fieldList[$table] = $this->buildFieldList($table); + } + return isset($fieldList[$table][$field]); + } + + /** + * build an array of all the columns of the named table + * + * @param string table name without prefix + * @return array keys for the field names and 1 for the values + */ + protected function buildFieldList($table) + { + $fieldList = array(); + + $fieldInfo = $this->db->show_fields_from($table); + foreach ($fieldInfo as $info) { + $fieldList[$info['Field']] = 1; + } + return $fieldList; + } + + /** + * build an array of all the installed themes + * + * @param bool acp or forum + * @return array keys of folder names + */ + private function buildThemeList($acp=false) + { + static $cache; + $folderList = array(); + + if ($acp === true) { + if (isset($cache['acp'])) { + return $cache['acp']; + } + + foreach (new DirectoryIterator(MYBB_ADMIN_DIR . 'styles') as $di) { + $folder = $di->getFilename(); + + if ($folder == 'default' || + $di->isDot() || + !$di->isDir() || + @!file_exists(MYBB_ADMIN_DIR . "styles/{$folder}/main.css")) { + continue; + } + + $folderList[] = $folder; + } + + $cache['acp'] = $folderList; + } else { + if (isset($cache['forum'])) { + return $cache['forum']; + } + + $duplicates = array('images' => 1); + $query = $this->db->simple_select('themes', 'pid, properties'); + while ($theme = $this->db->fetch_array($query)) { + $properties = unserialize($theme['properties']); + $folder = $properties['imgdir']; + + if (!isset($duplicates[$folder])) { + $duplicates[$folder] = 1; + $folderList[] = $folder; + } + } + + $cache['forum'] = $folderList; + } + + return $folderList; + } + + /** + * verify that path exists or can be created + * + * @param folder path + * @return bool + */ + private function createContentFolder($path) + { + if (mkdir($path, 0777, true)) { + file_put_contents($path . '/index.html', << + + + + + forbidden + + + +
you don't have permission to access this resource
+ + +EOF +); + + return true; + } + + return false; + } +} + +?> diff --git a/Upload/inc/plugins/sm/classes/WildcardPluginInstallerInterface010000.php b/Upload/inc/plugins/sm/classes/WildcardPluginInstallerInterface010000.php new file mode 100644 index 0000000..1fe26d6 --- /dev/null +++ b/Upload/inc/plugins/sm/classes/WildcardPluginInstallerInterface010000.php @@ -0,0 +1,13 @@ + diff --git a/Upload/inc/plugins/sm/classes/index.html b/Upload/inc/plugins/sm/classes/index.html new file mode 100644 index 0000000..0fd964c --- /dev/null +++ b/Upload/inc/plugins/sm/classes/index.html @@ -0,0 +1,27 @@ + + + + + + forbidden + + + +
you don't have permission to access this resource
+ + diff --git a/Upload/inc/plugins/sm/forum.php b/Upload/inc/plugins/sm/forum.php new file mode 100644 index 0000000..990d9a8 --- /dev/null +++ b/Upload/inc/plugins/sm/forum.php @@ -0,0 +1,156 @@ +
Please make sure IN_MYBB is defined.'); +} + +smInitialize(); + +/** + * add hooks and include functions only when appropriate + * + * return void + */ +function smInitialize() +{ + global $mybb, $plugins, $templatelist; + + $plugins->add_hook('global_intermediate', 'smBuildPopup'); + + // only add the xmlhttp hook if required + if (THIS_SCRIPT == 'xmlhttp.php' && + $mybb->input['action'] == 'sm') { + $plugins->add_hook('xmlhttp', 'smXmlhttp'); + } + + $templatelist .= ',sm_popup'; +} + +/** + * handles AJAX for Smile Menu + * + * @return void + */ +function smXmlhttp() +{ + global $mybb; + + $ajaxFunction = "smXmlhttp{$mybb->input['mode']}"; + if ($mybb->input['action'] != 'sm' || + !function_exists($ajaxFunction)) { + return; + } + + $ajaxFunction(); + return; +} + +function smCacheSmilies() +{ + global $cache, $mybb, $theme; + + static $localCache = null; + + if ($localCache === null) { + $localCache = array(); + + $smilies = $cache->read("smilies"); + if (is_array($smilies) && + !empty($smilies)) { + foreach ($smilies as $sid => $smilie) { + $smilie['find'] = explode("\n", $smilie['find']); + $smilie['image'] = str_replace("{theme}", $theme['imgdir'], $smilie['image']); + + foreach ($smilie['find'] as $s) { + $localCache[$s] = array( + 'title' => $smilie['name'], + 'code' => $s, + 'url' => $smilie['image'], + ); + } + } + } else { + $localCache = false; + } + } + + if ($localCache === false) { + return false; + } + + return $localCache; +} + +/** + * search for usernames beginning with search text and echo JSON + * + * @return void + */ +function smXmlhttpLoad() +{ + global $mybb, $db, $cache; + + $smilies = smCacheSmilies(); + + if (empty($smilies)) { + exit; + } + + $json = json_encode($smilies); + + // send our headers. + header('Content-type: application/json'); + echo($json); + exit; +} + +/** + * output the popup HTML + * + * @return void + */ +function smBuildPopup() { + global $mybb, $lang, $theme, $templates, $smAutocomplete; + + if (!$lang->sm) { + $lang->load('sm'); + } + + if ($mybb->settings['sm_minify_js']) { + $min = '.min'; + } + + $mybb->settings['sm_min_width'] = (int) $mybb->settings['sm_min_width']; + + $smAutocomplete = << + + + +EOF; + + eval("\$smAutocomplete .= \"" . $templates->get('sm_popup') . "\";"); +} + +?> diff --git a/Upload/inc/plugins/sm/index.html b/Upload/inc/plugins/sm/index.html new file mode 100644 index 0000000..0fd964c --- /dev/null +++ b/Upload/inc/plugins/sm/index.html @@ -0,0 +1,27 @@ + + + + + + forbidden + + + +
you don't have permission to access this resource
+ + diff --git a/Upload/inc/plugins/sm/install.php b/Upload/inc/plugins/sm/install.php new file mode 100644 index 0000000..c57e899 --- /dev/null +++ b/Upload/inc/plugins/sm/install.php @@ -0,0 +1,231 @@ +
Please make sure IN_MYBB is defined.'); +} + +/** + * used by MyBB to provide relevant information about the plugin and + * also link users to updates + * + * @return array plugin info + */ +function sm_info() +{ + global $db, $lang, $mybb, $cp_style; + + if (!$lang->sm) { + $lang->load('sm'); + } + + $settingsLink = smBuildSettingsLink(); + + // if MyAlerts is installed + if ($settingsLink) { + $settingsLink = << + {$settingsLink} + +EOF; + + $buttonPic = "styles/{$cp_style}/images/sm/donate.gif"; + $smDescription = << + + + {$lang->sm_description} +
    +{$settingsLink} +
+ + + {$lang->sm_logo} +
+
+ + + + +EOF; + } else { + $smDescription = $lang->sm_description; + } + + $name = "Smile Menu"; + $author = "Wildcard"; + + // return the info + return array( + 'name' => $name, + 'description' => $smDescription, + 'website' => 'https://github.com/WildcardSearch/Smile-Menu', + 'version' => SMILEMENU_VERSION, + 'author' => $author, + 'authorsite' => 'https://www.rantcentralforums.com/', + 'compatibility' => '18*', + 'codename' => 'sm', + ); +} + +/** + * check to see if the plugin is installed + * + * @return bool true if installed, false if not + */ +function sm_is_installed() +{ + return smGetSettingsgroup(); +} + +/** + * + * + * @return void + */ +function sm_install() +{ + global $db, $lang; + + if (!$lang->sm) { + $lang->load('sm'); + } + + SmileMenuInstaller::getInstance()->install(); +} + +/** + * edit the footer template + * + * @return void + */ +function sm_activate() +{ + global $plugins, $db, $cache, $lang, $smOldVersion; + + if (!$lang->sm) { + $lang->load('sm'); + } + + /* // version check + $smOldVersion = SmileMenuCache::getInstance()->getVersion(); + if (version_compare($smOldVersion, SMILEMENU_VERSION, '<') && + $smOldVersion != '' && + $smOldVersion != 0) { + require MYBB_ROOT . 'inc/plugins/sm/upgrade.php'; + } */ + + require_once MYBB_ROOT . '/inc/adminfunctions_templates.php'; + + // update the version (so we don't try to upgrade next round) + SmileMenuCache::getInstance()->setVersion(SMILEMENU_VERSION); + + // edit the templates + find_replace_templatesets('footer', '#^(.*?)$#s', '$1{$smAutocomplete}'); +} + +/** + * + * + * @return void + */ +function sm_deactivate() +{ + require_once MYBB_ROOT . '/inc/adminfunctions_templates.php'; + + find_replace_templatesets('footer', "#" . preg_quote('{$smAutocomplete}') . "#i", ''); +} + +/** + * delete setting group and settings, templates, + * and the style sheet + * + * undo MyAlerts integration and unset the cached version + * + * @return void + */ +function sm_uninstall() +{ + SmileMenuInstaller::getInstance()->uninstall(); + + SmileMenuCache::getInstance()->clear(); +} + +/** + * settings + */ + +/** + * retrieves the plugin's settings group gid if it exists + * attempts to cache repeat calls + * + * @return int setting group id + */ +function smGetSettingsgroup() +{ + static $gid; + + // if we have already stored the value + if (!isset($gid)) { + global $db; + + // otherwise we will have to query the db + $query = $db->simple_select("settinggroups", "gid", "name='sm_settings'"); + $gid = (int) $db->fetch_field($query, 'gid'); + } + return $gid; +} + +/** + * builds the URL to modify plugin settings if given valid info + * + * @param - $gid is an integer representing a valid settings group id + * @return string setting group URL + */ +function smBuildSettingsURL($gid) +{ + if ($gid) { + return 'index.php?module=config-settings&action=change&gid='.$gid; + } +} + +/** + * builds a link to modify plugin settings if it exists + * + * @return setting group link HTML + */ +function smBuildSettingsLink() +{ + global $lang; + + if (!$lang->sm) { + $lang->load('sm'); + } + + $gid = smGetSettingsgroup(); + + // does the group exist? + if ($gid) { + // if so build the URL + $url = smBuildSettingsURL($gid); + + // did we get a URL? + if ($url) { + // if so build the link + return <<{$lang->sm_plugin_settings} +EOF; + } + } + return false; +} + +?> diff --git a/Upload/inc/plugins/sm/install_data.php b/Upload/inc/plugins/sm/install_data.php new file mode 100644 index 0000000..84228e9 --- /dev/null +++ b/Upload/inc/plugins/sm/install_data.php @@ -0,0 +1,220 @@ + array( + 'group' => array( + 'name' => 'sm_settings', + 'title' => $lang->sm_plugin_settings_title, + 'description' => $lang->sm_settingsgroup_description, + 'disporder' => '102', + 'isdefault' => 0, + ), + 'settings' => array( + 'sm_max_items' => array( + 'sid' => '0', + 'name' => 'sm_max_items', + 'title' => $lang->sm_max_items_title, + 'description' => $lang->sm_max_items_description, + 'optionscode' => 'text', + 'value' => '5', + 'disporder' => '10', + ), + 'sm_min_width' => array( + 'sid' => '0', + 'name' => 'sm_min_width', + 'title' => $lang->sm_min_width_title, + 'description' => $lang->sm_min_width_description, + 'optionscode' => 'text', + 'value' => '120', + 'disporder' => '20', + ), + 'sm_full_text_search' => array( + 'sid' => '0', + 'name' => 'sm_full_text_search', + 'title' => $lang->sm_full_text_search_title, + 'description' => $lang->sm_full_text_search_description, + 'optionscode' => 'yesno', + 'value' => '0', + 'disporder' => '30', + ), + 'sm_lock_selection' => array( + 'sid' => '0', + 'name' => 'sm_lock_selection', + 'title' => $lang->sm_lock_selection_title, + 'description' => $lang->sm_lock_selection_description, + 'optionscode' => 'yesno', + 'value' => '1', + 'disporder' => '40', + ), + 'sm_minify_js' => array( + 'sid' => '0', + 'name' => 'sm_minify_js', + 'title' => $lang->sm_minify_js_title, + 'description' => $lang->sm_minify_js_desc, + 'optionscode' => 'yesno', + 'value' => '1', + 'disporder' => '50', + ), + ) + ) +); + +$templates = array( + 'sm' => array( + 'group' => array( + 'prefix' => 'sm', + 'title' => $lang->sm, + ), + 'templates' => array( + 'sm_popup' => <<