Seditio Source
Root |
./othercms/dotclear-2.22/admin/services.php
<?php
/**
 * @package Dotclear
 * @subpackage Backend
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 *
 * @var dcCore $core
 */
require __DIR__ . '/../inc/admin/prepend.php';

$core->rest->addFunction('getPostsCount', ['dcRestMethods', 'getPostsCount']);
$core->rest->addFunction('getCommentsCount', ['dcRestMethods', 'getCommentsCount']);
$core->rest->addFunction('checkNewsUpdate', ['dcRestMethods', 'checkNewsUpdate']);
$core->rest->addFunction('checkCoreUpdate', ['dcRestMethods', 'checkCoreUpdate']);
$core->rest->addFunction('checkStoreUpdate', ['dcRestMethods', 'checkStoreUpdate']);
$core->rest->addFunction('getPostById', ['dcRestMethods', 'getPostById']);
$core->rest->addFunction('getCommentById', ['dcRestMethods', 'getCommentById']);
$core->rest->addFunction('quickPost', ['dcRestMethods', 'quickPost']);
$core->rest->addFunction('validatePostMarkup', ['dcRestMethods', 'validatePostMarkup']);
$core->rest->addFunction('getZipMediaContent', ['dcRestMethods', 'getZipMediaContent']);
$core->rest->addFunction('getMeta', ['dcRestMethods', 'getMeta']);
$core->rest->addFunction('delMeta', ['dcRestMethods', 'delMeta']);
$core->rest->addFunction('setPostMeta', ['dcRestMethods', 'setPostMeta']);
$core->rest->addFunction('searchMeta', ['dcRestMethods', 'searchMeta']);
$core->rest->addFunction('setSectionFold', ['dcRestMethods', 'setSectionFold']);
$core->rest->addFunction('getModuleById', ['dcRestMethods', 'getModuleById']);
$core->rest->addFunction('setDashboardPositions', ['dcRestMethods', 'setDashboardPositions']);
$core->rest->addFunction('setListsOptions', ['dcRestMethods', 'setListsOptions']);

$core->rest->serve();

/* Common REST methods */
class dcRestMethods
{
   
/**
     * Serve method to get number of posts (whatever are their status) for current blog.
     *
     * @param     dcCore  $core     dcCore instance
     * @param     array   $get     cleaned $_GET
     */
   
public static function getPostsCount($core, $get)
    {
       
$count = $core->blog->getPosts([], true)->f(0);
       
$str   = sprintf(__('%d post', '%d posts', $count), $count);

       
$rsp      = new xmlTag('count');
       
$rsp->ret = $str;

        return
$rsp;
    }

   
/**
     * Serve method to get number of comments (whatever are their status) for current blog.
     *
     * @param     dcCore  $core     dcCore instance
     * @param     array   $get     cleaned $_GET
     */
   
public static function getCommentsCount($core, $get)
    {
       
$count = $core->blog->getComments([], true)->f(0);
       
$str   = sprintf(__('%d comment', '%d comments', $count), $count);

       
$rsp      = new xmlTag('count');
       
$rsp->ret = $str;

        return
$rsp;
    }

    public static function
checkNewsUpdate($core, $get)
    {
       
# Dotclear news

       
$rsp        = new xmlTag('news');
       
$rsp->check = false;
       
$ret        = __('Dotclear news not available');

        if (
$core->auth->user_prefs->dashboard->dcnews) {
            try {
                if (empty(
$GLOBALS['__resources']['rss_news'])) {
                    throw new
Exception();
                }
               
$feed_reader = new feedReader();
               
$feed_reader->setCacheDir(DC_TPL_CACHE);
               
$feed_reader->setTimeout(2);
               
$feed_reader->setUserAgent('Dotclear - https://dotclear.org/');
               
$feed = $feed_reader->parse($GLOBALS['__resources']['rss_news']);
                if (
$feed) {
                   
$ret = '<div class="box medium dc-box" id="ajax-news"><h3>' . __('Dotclear news') . '</h3><dl id="news">';
                   
$i   = 1;
                    foreach (
$feed->items as $item) {
                       
/* @phpstan-ignore-next-line */
                       
$dt = isset($item->link) ? '<a href="' . $item->link . '" class="outgoing" title="' . $item->title . '">' .
                       
/* @phpstan-ignore-next-line */
                       
$item->title . ' <img src="images/outgoing-link.svg" alt="" /></a>' : $item->title;
                       
$ret .= '<dt>' . $dt . '</dt>' .
                       
'<dd><p><strong>' . dt::dt2str(__('%d %B %Y:'), $item->pubdate, 'Europe/Paris') . '</strong> ' .
                       
'<em>' . text::cutString(html::clean($item->content), 120) . '...</em></p></dd>';
                       
$i++;
                        if (
$i > 2) {
                            break;
                        }
                    }
                   
$ret .= '</dl></div>';
                   
$rsp->check = true;
                }
            } catch (
Exception $e) {
            }
        }
       
$rsp->ret = $ret;

        return
$rsp;
    }

    public static function
checkCoreUpdate($core, $get)
    {
       
# Dotclear updates notifications

       
$rsp        = new xmlTag('update');
       
$rsp->check = false;
       
$ret        = __('Dotclear update not available');

       
/* @phpstan-ignore-next-line */
       
if ($core->auth->isSuperAdmin() && !DC_NOT_UPDATE && is_readable(DC_DIGESTS) && !$core->auth->user_prefs->dashboard->nodcupdate) {
           
$updater      = new dcUpdate(DC_UPDATE_URL, 'dotclear', DC_UPDATE_VERSION, DC_TPL_CACHE . '/versions');
           
$new_v        = $updater->check(DC_VERSION);
           
$version_info = $new_v ? $updater->getInfoURL() : '';

            if (
$updater->getNotify() && $new_v) {
               
// Check PHP version required
               
if (version_compare(phpversion(), $updater->getPHPVersion()) >= 0) {
                   
$ret = '<div class="dc-update" id="ajax-update"><h3>' . sprintf(__('Dotclear %s is available!'), $new_v) . '</h3> ' .
                   
'<p><a class="button submit" href="' . $core->adminurl->get('admin.update') . '">' . sprintf(__('Upgrade now'), $new_v) . '</a> ' .
                   
'<a class="button" href="' . $core->adminurl->get('admin.update', ['hide_msg' => 1]) . '">' . __('Remind me later') . '</a>' .
                        (
$version_info ? ' </p>' .
                       
'<p class="updt-info"><a href="' . $version_info . '">' . __('Information about this version') . '</a>' : '') . '</p>' .
                       
'</div>';
                } else {
                   
$ret = '<p class="info">' .
                   
sprintf(
                       
__('A new version of Dotclear is available but needs PHP version ≥ %s, your\'s is currently %s'),
                       
$updater->getPHPVersion(),
                       
phpversion()
                    ) .
                       
'</p>';
                }
               
$rsp->check = true;
            } else {
                if (
version_compare(phpversion(), DC_NEXT_REQUIRED_PHP, '<')) {
                    if (!
$core->auth->user_prefs->interface->hidemoreinfo) {
                       
$ret = '<p class="info">' .
                       
sprintf(
                           
__('The next versions of Dotclear will not support PHP version < %s, your\'s is currently %s'),
                           
DC_NEXT_REQUIRED_PHP,
                           
phpversion()
                        ) .
                       
'</p>';
                       
$rsp->check = true;
                    }
                }
            }
        }
       
$rsp->ret = $ret;

        return
$rsp;
    }

    public static function
checkStoreUpdate($core, $get, $post)
    {
       
# Dotclear store updates notifications

       
$rsp        = new xmlTag('update');
       
$rsp->check = false;
       
$rsp->nb    = 0;
       
$ret        = __('No updates are available');
       
$mod        = '';
       
$url        = '';

        if (empty(
$post['store'])) {
            throw new
Exception('No store type');
        }

        if (
$post['store'] == 'themes') {
           
$mod = new dcThemes($core);
           
$mod->loadModules($core->blog->themes_path, null);
           
$url = $core->blog->settings->system->store_theme_url;
        } elseif (
$post['store'] == 'plugins') {
           
$mod = $core->plugins;
           
$url = $core->blog->settings->system->store_plugin_url;
        } else {

           
# --BEHAVIOR-- restCheckStoreUpdate
           
$core->callBehavior('restCheckStoreUpdate', $core, $post['store'], [& $mod], [& $url]);

            if (empty(
$mod) || empty($url)) {   // @phpstan-ignore-line
               
throw new Exception('Unknown store type');
            }
        }

       
$repo = new dcStore($mod, $url);
       
$upd  = $repo->get(true);
        if (!empty(
$upd)) {
           
$ret        = sprintf(__('An update is available', '%s updates are available.', count($upd)), count($upd));
           
$rsp->check = true;
           
$rsp->nb    = count($upd);
        }

       
$rsp->ret = $ret;

        return
$rsp;
    }

    public static function
getPostById($core, $get)
    {
        if (empty(
$get['id'])) {
            throw new
Exception('No post ID');
        }

       
$params = ['post_id' => (int) $get['id']];

        if (isset(
$get['post_type'])) {
           
$params['post_type'] = $get['post_type'];
        }

       
$rs = $core->blog->getPosts($params);

        if (
$rs->isEmpty()) {
            throw new
Exception('No post for this ID');
        }

       
$rsp     = new xmlTag('post');
       
$rsp->id = $rs->post_id;

       
$rsp->blog_id($rs->blog_id);
       
$rsp->user_id($rs->user_id);
       
$rsp->cat_id($rs->cat_id);
       
$rsp->post_dt($rs->post_dt);
       
$rsp->post_creadt($rs->post_creadt);
       
$rsp->post_upddt($rs->post_upddt);
       
$rsp->post_format($rs->post_format);
       
$rsp->post_url($rs->post_url);
       
$rsp->post_lang($rs->post_lang);
       
$rsp->post_title($rs->post_title);
       
$rsp->post_excerpt($rs->post_excerpt);
       
$rsp->post_excerpt_xhtml($rs->post_excerpt_xhtml);
       
$rsp->post_content($rs->post_content);
       
$rsp->post_content_xhtml($rs->post_content_xhtml);
       
$rsp->post_notes($rs->post_notes);
       
$rsp->post_status($rs->post_status);
       
$rsp->post_selected($rs->post_selected);
       
$rsp->post_open_comment($rs->post_open_comment);
       
$rsp->post_open_tb($rs->post_open_tb);
       
$rsp->nb_comment($rs->nb_comment);
       
$rsp->nb_trackback($rs->nb_trackback);
       
$rsp->user_name($rs->user_name);
       
$rsp->user_firstname($rs->user_firstname);
       
$rsp->user_displayname($rs->user_displayname);
       
$rsp->user_email($rs->user_email);
       
$rsp->user_url($rs->user_url);
       
$rsp->cat_title($rs->cat_title);
       
$rsp->cat_url($rs->cat_url);

       
$rsp->post_display_content($rs->getContent(true));
       
$rsp->post_display_excerpt($rs->getExcerpt(true));

       
$metaTag = new xmlTag('meta');
        if ((
$meta = @unserialize($rs->post_meta)) !== false) {
            foreach (
$meta as $K => $V) {
                foreach (
$V as $v) {
                   
$metaTag->$K($v);
                }
            }
        }
       
$rsp->post_meta($metaTag);

        return
$rsp;
    }

    public static function
getCommentById($core, $get)
    {
        if (empty(
$get['id'])) {
            throw new
Exception('No comment ID');
        }

       
$rs = $core->blog->getComments(['comment_id' => (int) $get['id']]);

        if (
$rs->isEmpty()) {
            throw new
Exception('No comment for this ID');
        }

       
$rsp     = new xmlTag('post');
       
$rsp->id = $rs->comment_id;

       
$rsp->comment_dt($rs->comment_dt);
       
$rsp->comment_upddt($rs->comment_upddt);
       
$rsp->comment_author($rs->comment_author);
       
$rsp->comment_site($rs->comment_site);
       
$rsp->comment_content($rs->comment_content);
       
$rsp->comment_trackback($rs->comment_trackback);
       
$rsp->comment_status($rs->comment_status);
       
$rsp->post_title($rs->post_title);
       
$rsp->post_url($rs->post_url);
       
$rsp->post_id($rs->post_id);
       
$rsp->post_dt($rs->post_dt);
       
$rsp->user_id($rs->user_id);

       
$rsp->comment_display_content($rs->getContent(true));

        if (
$core->auth->userID()) {
           
$rsp->comment_ip($rs->comment_ip);
           
$rsp->comment_email($rs->comment_email);
           
$rsp->comment_spam_disp(dcAntispam::statusMessage($rs));
        }

        return
$rsp;
    }

    public static function
quickPost($core, $get, $post)
    {
       
# Create category
       
if (!empty($post['new_cat_title']) && $core->auth->check('categories', $core->blog->id)) {
           
$cur_cat            = $core->con->openCursor($core->prefix . 'category');
           
$cur_cat->cat_title = $post['new_cat_title'];
           
$cur_cat->cat_url   = '';

           
$parent_cat = !empty($post['new_cat_parent']) ? $post['new_cat_parent'] : '';

           
# --BEHAVIOR-- adminBeforeCategoryCreate
           
$core->callBehavior('adminBeforeCategoryCreate', $cur_cat);

           
$post['cat_id'] = $core->blog->addCategory($cur_cat, (int) $parent_cat);

           
# --BEHAVIOR-- adminAfterCategoryCreate
           
$core->callBehavior('adminAfterCategoryCreate', $cur_cat, $post['cat_id']);
        }

       
$cur = $core->con->openCursor($core->prefix . 'post');

       
$cur->post_title        = !empty($post['post_title']) ? $post['post_title'] : '';
       
$cur->user_id           = $core->auth->userID();
       
$cur->post_content      = !empty($post['post_content']) ? $post['post_content'] : '';
       
$cur->cat_id            = !empty($post['cat_id']) ? (int) $post['cat_id'] : null;
       
$cur->post_format       = !empty($post['post_format']) ? $post['post_format'] : 'xhtml';
       
$cur->post_lang         = !empty($post['post_lang']) ? $post['post_lang'] : '';
       
$cur->post_status       = !empty($post['post_status']) ? (int) $post['post_status'] : 0;
       
$cur->post_open_comment = (int) $core->blog->settings->system->allow_comments;
       
$cur->post_open_tb      = (int) $core->blog->settings->system->allow_trackbacks;

       
# --BEHAVIOR-- adminBeforePostCreate
       
$core->callBehavior('adminBeforePostCreate', $cur);

       
$return_id = $core->blog->addPost($cur);

       
# --BEHAVIOR-- adminAfterPostCreate
       
$core->callBehavior('adminAfterPostCreate', $cur, $return_id);

       
$rsp     = new xmlTag('post');
       
$rsp->id = $return_id;

       
$post = $core->blog->getPosts(['post_id' => $return_id]);

       
$rsp->post_status = $post->post_status;
       
$rsp->post_url    = $post->getURL();

        return
$rsp;
    }

    public static function
validatePostMarkup($core, $get, $post)
    {
        if (!isset(
$post['excerpt'])) {
            throw new
Exception('No entry excerpt');
        }

        if (!isset(
$post['content'])) {
            throw new
Exception('No entry content');
        }

        if (empty(
$post['format'])) {
            throw new
Exception('No entry format');
        }

        if (!isset(
$post['lang'])) {
            throw new
Exception('No entry lang');
        }

       
$excerpt       = $post['excerpt'];
       
$excerpt_xhtml = '';
       
$content       = $post['content'];
       
$content_xhtml = '';
       
$format        = $post['format'];
       
$lang          = $post['lang'];

       
$core->blog->setPostContent(0, $format, $lang, $excerpt, $excerpt_xhtml, $content, $content_xhtml);

       
$rsp = new xmlTag('result');

       
$v = htmlValidator::validate($excerpt_xhtml . $content_xhtml);

       
$rsp->valid($v['valid']);
       
$rsp->errors($v['errors']);

        return
$rsp;
    }

    public static function
getZipMediaContent($core, $get, $post)
    {
        if (empty(
$get['id'])) {
            throw new
Exception('No media ID');
        }

       
$id = (int) $get['id'];

        if (!
$core->auth->check('media,media_admin', $core->blog)) {
            throw new
Exception('Permission denied');
        }

       
$file = null;

        try {
           
$core->media = new dcMedia($core);
           
$file        = $core->media->getFile($id);
        } catch (
Exception $e) {
        }

        if (
$file === null || $file->type != 'application/zip' || !$file->editable) {
            throw new
Exception('Not a valid file');
        }

       
$rsp     = new xmlTag('result');
       
$content = $core->media->getZipContent($file);

        foreach (
$content as $k => $v) {
           
$rsp->file($k);
        }

        return
$rsp;
    }

    public static function
getMeta($core, $get)
    {
       
$postid   = !empty($get['postId']) ? $get['postId'] : null;
       
$limit    = !empty($get['limit']) ? $get['limit'] : null;
       
$metaId   = !empty($get['metaId']) ? $get['metaId'] : null;
       
$metaType = !empty($get['metaType']) ? $get['metaType'] : null;

       
$sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc';

       
$rs = $core->meta->getMetadata([
           
'meta_type' => $metaType,
           
'limit'     => $limit,
           
'meta_id'   => $metaId,
           
'post_id'   => $postid, ]);
       
$rs = $core->meta->computeMetaStats($rs);

       
$sortby = explode(',', $sortby);
       
$sort   = $sortby[0];
       
$order  = $sortby[1] ?? 'asc';

        switch (
$sort) {
            case
'metaId':
               
$sort = 'meta_id_lower';

                break;
            case
'count':
               
$sort = 'count';

                break;
            case
'metaType':
               
$sort = 'meta_type';

                break;
            default:
               
$sort = 'meta_type';
        }

       
$rs->sort($sort, $order);

       
$rsp = new xmlTag();

        while (
$rs->fetch()) {
           
$metaTag               = new xmlTag('meta');
           
$metaTag->type         = $rs->meta_type;
           
$metaTag->uri          = rawurlencode($rs->meta_id);
           
$metaTag->count        = $rs->count;
           
$metaTag->percent      = $rs->percent;
           
$metaTag->roundpercent = $rs->roundpercent;
           
$metaTag->CDATA($rs->meta_id);

           
$rsp->insertNode($metaTag);
        }

        return
$rsp;
    }

    public static function
setPostMeta($core, $get, $post)
    {
        if (empty(
$post['postId'])) {
            throw new
Exception('No post ID');
        }

        if (empty(
$post['meta']) && $post['meta'] != '0') {
            throw new
Exception('No meta');
        }

        if (empty(
$post['metaType'])) {
            throw new
Exception('No meta type');
        }

       
# Get previous meta for post
       
$post_meta = $core->meta->getMetadata([
           
'meta_type' => $post['metaType'],
           
'post_id'   => $post['postId'], ]);
       
$pm = [];
        while (
$post_meta->fetch()) {
           
$pm[] = $post_meta->meta_id;
        }

        foreach (
$core->meta->splitMetaValues($post['meta']) as $m) {
            if (!
in_array($m, $pm)) {
               
$core->meta->setPostMeta($post['postId'], $post['metaType'], $m);
            }
        }

        return
true;
    }

    public static function
delMeta($core, $get, $post)
    {
        if (empty(
$post['postId'])) {
            throw new
Exception('No post ID');
        }

        if (empty(
$post['metaId']) && $post['metaId'] != '0') {
            throw new
Exception('No meta ID');
        }

        if (empty(
$post['metaType'])) {
            throw new
Exception('No meta type');
        }

       
$core->meta->delPostMeta($post['postId'], $post['metaType'], $post['metaId']);

        return
true;
    }

    public static function
searchMeta($core, $get)
    {
       
$q        = !empty($get['q']) ? $get['q'] : null;
       
$metaType = !empty($get['metaType']) ? $get['metaType'] : null;

       
$sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc';

       
$rs = $core->meta->getMetadata(['meta_type' => $metaType]);
       
$rs = $core->meta->computeMetaStats($rs);

       
$sortby = explode(',', $sortby);
       
$sort   = $sortby[0];
       
$order  = $sortby[1] ?? 'asc';

        switch (
$sort) {
            case
'metaId':
               
$sort = 'meta_id_lower';

                break;
            case
'count':
               
$sort = 'count';

                break;
            case
'metaType':
               
$sort = 'meta_type';

                break;
            default:
               
$sort = 'meta_type';
        }

       
$rs->sort($sort, $order);

       
$rsp = new xmlTag();

        while (
$rs->fetch()) {
            if (
stripos($rs->meta_id, $q) === 0) {
               
$metaTag               = new xmlTag('meta');
               
$metaTag->type         = $rs->meta_type;
               
$metaTag->uri          = rawurlencode($rs->meta_id);
               
$metaTag->count        = $rs->count;
               
$metaTag->percent      = $rs->percent;
               
$metaTag->roundpercent = $rs->roundpercent;
               
$metaTag->CDATA($rs->meta_id);

               
$rsp->insertNode($metaTag);
            }
        }

        return
$rsp;
    }

    public static function
setSectionFold($core, $get, $post)
    {
        if (empty(
$post['section'])) {
            throw new
Exception('No section name');
        }
        if (
$core->auth->user_prefs->toggles === null) {
           
$core->auth->user_prefs->addWorkspace('toggles');
        }
       
$section = $post['section'];
       
$status  = isset($post['value']) && ($post['value'] != 0);
        if (
$core->auth->user_prefs->toggles->prefExists('unfolded_sections')) {
           
$toggles = explode(',', trim((string) $core->auth->user_prefs->toggles->unfolded_sections));
        } else {
           
$toggles = [];
        }
       
$k = array_search($section, $toggles);
        if (
$status) {
           
// true == Fold section ==> remove it from unfolded list
           
if ($k !== false) {
                unset(
$toggles[$k]);
            }
        } else {
           
// false == unfold section ==> add it to unfolded list
           
if ($k === false) {
               
$toggles[] = $section;
            };
        }
       
$core->auth->user_prefs->toggles->put('unfolded_sections', join(',', $toggles));

        return
true;
    }

    public static function
setDashboardPositions($core, $get, $post)
    {
        if (empty(
$post['id'])) {
            throw new
Exception('No zone name');
        }
        if (empty(
$post['list'])) {
            throw new
Exception('No sorted list of id');
        }

        if (
$core->auth->user_prefs->dashboard === null) {
           
$core->auth->user_prefs->addWorkspace('dashboard');
        }

       
$zone  = $post['id'];
       
$order = $post['list'];

       
$core->auth->user_prefs->dashboard->put($zone, $order);

        return
true;
    }

    public static function
setListsOptions($core, $get, $post)
    {
        if (empty(
$post['id'])) {
            throw new
Exception('No list name');
        }

       
$sorts = adminUserPref::getUserFilters();

        if (!isset(
$sorts[$post['id']])) {
            throw new
Exception('List name invalid');
        }

       
$res = new xmlTag('result');

       
$su = [];
        foreach (
$sorts as $sort_type => $sort_data) {
            if (
null !== $sort_data[1]) {
               
$k                 = 'sort';
               
$su[$sort_type][0] = $sort_type == $post['id'] && isset($post[$k]) && in_array($post[$k], $sort_data[1]) ? $post[$k] : $sort_data[2];
            }
            if (
null !== $sort_data[3]) {
               
$k                 = 'order';
               
$su[$sort_type][1] = $sort_type == $post['id'] && isset($post[$k]) && in_array($post[$k], ['asc', 'desc']) ? $post[$k] : $sort_data[3];
            }
            if (
null !== $sort_data[4]) {
               
$k                 = 'nb';
               
$su[$sort_type][2] = $sort_type == $post['id'] && isset($post[$k]) ? abs((int) $post[$k]) : $sort_data[4][1];
            }
        }
        if (
$core->auth->user_prefs->interface === null) {
           
$core->auth->user_prefs->addWorkspace('interface');
        }
       
$core->auth->user_prefs->interface->put('sorts', $su, 'array');

       
$res->msg = __('List options saved');

        return
$res;
    }

    public static function
getModuleById($core, $get, $post)
    {
        if (empty(
$get['id'])) {
            throw new
Exception('No module ID');
        }
        if (empty(
$get['list'])) {
            throw new
Exception('No list ID');
        }

       
$id     = $get['id'];
       
$list   = $get['list'];
       
$module = [];

        if (
$list == 'plugin-activate') {
           
$modules = $core->plugins->getModules();
            if (empty(
$modules) || !isset($modules[$id])) {
                throw new
Exception('Unknown module ID');
            }
           
$module = $modules[$id];
        } elseif (
$list == 'plugin-new') {
           
$store = new dcStore(
               
$core->plugins,
               
$core->blog->settings->system->store_plugin_url
           
);
           
$store->check();

           
$modules = $store->get();
            if (empty(
$modules) || !isset($modules[$id])) {
                throw new
Exception('Unknown module ID');
            }
           
$module = $modules[$id];
        }
       
// behavior not implemented yet

       
if (empty($module)) {
            throw new
Exception('Unknown module ID');
        }

       
$module = adminModulesList::sanitizeModule($id, $module);

       
$rsp     = new xmlTag('module');
       
$rsp->id = $id;

        foreach (
$module as $k => $v) {
           
$rsp->{$k}((string) $v);
        }

        return
$rsp;
    }
}