2018-07-08 21:24:59 +02:00
|
|
|
<?php
|
2018-08-18 04:31:46 +02:00
|
|
|
define('MSZ_PERM_NEWS_MANAGE_POSTS', 1);
|
|
|
|
define('MSZ_PERM_NEWS_MANAGE_CATEGORIES', 1 << 1);
|
2018-10-10 11:21:57 +02:00
|
|
|
|
2018-10-11 23:43:52 +02:00
|
|
|
function news_post_create(
|
|
|
|
string $title,
|
|
|
|
string $text,
|
|
|
|
int $category,
|
|
|
|
int $user,
|
|
|
|
bool $featured = false,
|
|
|
|
?int $scheduled = null,
|
|
|
|
?int $postId = null
|
|
|
|
): int {
|
|
|
|
if ($postId < 1) {
|
|
|
|
$post = db_prepare('
|
|
|
|
INSERT INTO `msz_news_posts`
|
|
|
|
(`category_id`, `user_id`, `post_is_featured`, `post_title`, `post_text`, `post_scheduled`)
|
|
|
|
VALUES
|
|
|
|
(:category, :user, :featured, :title, :text, COALESCE(:scheduled, CURRENT_TIMESTAMP))
|
|
|
|
');
|
|
|
|
} else {
|
|
|
|
$post = db_prepare('
|
|
|
|
UPDATE `msz_news_posts`
|
|
|
|
SET `category_id` = :category,
|
|
|
|
`user_id` = :user,
|
|
|
|
`post_is_featured` = :featured,
|
|
|
|
`post_title` = :title,
|
|
|
|
`post_text` = :text,
|
|
|
|
`post_scheduled` = COALESCE(:scheduled, `post_scheduled`)
|
|
|
|
WHERE `post_id` = :id
|
|
|
|
');
|
|
|
|
$post->bindValue('id', $postId);
|
|
|
|
}
|
|
|
|
|
|
|
|
$post->bindValue('title', $title);
|
|
|
|
$post->bindValue('text', $text);
|
|
|
|
$post->bindValue('category', $category);
|
|
|
|
$post->bindValue('user', $user);
|
|
|
|
$post->bindValue('featured', $featured ? 1 : 0);
|
|
|
|
$post->bindValue('scheduled', empty($scheduled) ? null : date('Y-m-d H:i:s', $scheduled));
|
|
|
|
|
|
|
|
return $post->execute() ? ($postId < 1 ? (int)db_last_insert_id() : $postId) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function news_category_create(string $name, string $description, bool $isHidden, ?int $categoryId = null): int
|
|
|
|
{
|
|
|
|
if ($categoryId < 1) {
|
|
|
|
$category = db_prepare('
|
|
|
|
INSERT INTO `msz_news_categories`
|
|
|
|
(`category_name`, `category_description`, `category_is_hidden`)
|
|
|
|
VALUES
|
|
|
|
(:name, :description, :hidden)
|
|
|
|
');
|
|
|
|
} else {
|
|
|
|
$category = db_prepare('
|
|
|
|
UPDATE `msz_news_categories`
|
|
|
|
SET `category_name` = :name,
|
|
|
|
`category_description` = :description,
|
|
|
|
`category_is_hidden` = :hidden
|
|
|
|
WHERE `category_id` = :id
|
|
|
|
');
|
|
|
|
$category->bindValue('id', $categoryId);
|
|
|
|
}
|
|
|
|
|
|
|
|
$category->bindValue('name', $name);
|
|
|
|
$category->bindValue('description', $description);
|
|
|
|
$category->bindValue('hidden', $isHidden ? 1 : 0);
|
|
|
|
|
|
|
|
return $category->execute() ? ($categoryId < 1 ? (int)db_last_insert_id() : $categoryId) : 0;
|
|
|
|
}
|
|
|
|
|
2018-10-10 11:21:57 +02:00
|
|
|
function news_categories_get(
|
|
|
|
int $offset,
|
|
|
|
int $take,
|
|
|
|
bool $includePostCount = false,
|
|
|
|
bool $featuredOnly = false,
|
2018-10-11 23:43:52 +02:00
|
|
|
bool $includeHidden = false,
|
2018-10-10 11:21:57 +02:00
|
|
|
bool $exposeScheduled = false,
|
|
|
|
bool $excludeDeleted = true
|
|
|
|
): array {
|
|
|
|
$getAll = $offset < 0 || $take < 1;
|
|
|
|
|
|
|
|
if ($includePostCount) {
|
|
|
|
$query = sprintf(
|
|
|
|
'
|
|
|
|
SELECT
|
2018-10-22 23:18:13 +02:00
|
|
|
c.`category_id`, c.`category_name`, c.`category_is_hidden`,
|
|
|
|
c.`category_created`,
|
2018-10-10 11:21:57 +02:00
|
|
|
(
|
2018-10-22 23:18:13 +02:00
|
|
|
SELECT COUNT(p.`post_id`)
|
|
|
|
FROM `msz_news_posts` as p
|
|
|
|
WHERE p.`category_id` = c.`category_id` %2$s %3$s %4$s
|
2018-10-10 11:21:57 +02:00
|
|
|
) as `posts_count`
|
2018-10-22 23:18:13 +02:00
|
|
|
FROM `msz_news_categories` as c
|
2018-10-11 23:43:52 +02:00
|
|
|
%5$s
|
2018-10-22 23:18:13 +02:00
|
|
|
GROUP BY c.`category_id`
|
|
|
|
ORDER BY c.`category_id` DESC
|
2018-10-10 11:21:57 +02:00
|
|
|
%1$s
|
|
|
|
',
|
|
|
|
$getAll ? '' : 'LIMIT :offset, :take',
|
2018-10-22 23:18:13 +02:00
|
|
|
$featuredOnly ? 'AND p.`post_is_featured` != 0' : '',
|
|
|
|
$exposeScheduled ? '' : 'AND p.`post_scheduled` < NOW()',
|
|
|
|
$excludeDeleted ? 'AND p.`post_deleted` IS NULL' : '',
|
|
|
|
$includeHidden ? '' : 'WHERE c.`category_is_hidden` = 0'
|
2018-10-10 11:21:57 +02:00
|
|
|
);
|
|
|
|
} else {
|
2018-10-22 23:18:13 +02:00
|
|
|
$query = sprintf(
|
|
|
|
'
|
|
|
|
SELECT
|
|
|
|
`category_id`, `category_name`, `category_is_hidden`,
|
|
|
|
`category_created`
|
|
|
|
FROM `msz_news_categories`
|
|
|
|
%2$s
|
|
|
|
ORDER BY `category_id` DESC
|
|
|
|
%1$s
|
|
|
|
',
|
|
|
|
$getAll ? '' : 'LIMIT :offset, :take',
|
|
|
|
$includeHidden ? '' : 'WHERE c.`category_is_hidden` != 0'
|
|
|
|
);
|
2018-10-10 11:21:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$getCats = db_prepare($query);
|
|
|
|
|
|
|
|
if (!$getAll) {
|
|
|
|
$getCats->bindValue('offset', $offset);
|
|
|
|
$getCats->bindValue('take', $take);
|
|
|
|
}
|
|
|
|
|
2019-01-09 20:06:02 +01:00
|
|
|
return db_fetch_all($getCats);
|
2018-10-10 11:21:57 +02:00
|
|
|
}
|
|
|
|
|
2018-10-11 23:43:52 +02:00
|
|
|
function news_categories_count(bool $includeHidden = false): int
|
|
|
|
{
|
|
|
|
$countCats = db_prepare(sprintf('
|
|
|
|
SELECT COUNT(`category_id`)
|
|
|
|
FROM `msz_news_categories`
|
|
|
|
%s
|
|
|
|
', $includeHidden ? '' : 'WHERE `category_is_hidden` = 0'));
|
|
|
|
|
|
|
|
return $countCats->execute() ? (int)$countCats->fetchColumn() : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function news_category_get(
|
2018-10-10 11:21:57 +02:00
|
|
|
int $category,
|
|
|
|
bool $includePostCount = false,
|
|
|
|
bool $featuredOnly = false,
|
|
|
|
bool $exposeScheduled = false,
|
|
|
|
bool $excludeDeleted = true
|
|
|
|
): array {
|
|
|
|
if ($includePostCount) {
|
|
|
|
$query = sprintf(
|
|
|
|
'
|
|
|
|
SELECT
|
2018-10-22 23:18:13 +02:00
|
|
|
c.`category_id`, c.`category_name`, c.`category_description`,
|
|
|
|
c.`category_is_hidden`, c.`category_created`,
|
2018-10-11 23:43:52 +02:00
|
|
|
(
|
2018-10-22 23:18:13 +02:00
|
|
|
SELECT COUNT(p.`post_id`)
|
|
|
|
FROM `msz_news_posts` as p
|
|
|
|
WHERE p.`category_id` = c.`category_id` %1$s %2$s %3$s
|
2018-10-11 23:43:52 +02:00
|
|
|
) as `posts_count`
|
2018-10-22 23:18:13 +02:00
|
|
|
FROM `msz_news_categories` as c
|
|
|
|
WHERE c.`category_id` = :category
|
|
|
|
GROUP BY c.`category_id`
|
2018-10-10 11:21:57 +02:00
|
|
|
',
|
2018-10-22 23:18:13 +02:00
|
|
|
$featuredOnly ? 'AND p.`post_is_featured` != 0' : '',
|
|
|
|
$exposeScheduled ? '' : 'AND p.`post_scheduled` < NOW()',
|
|
|
|
$excludeDeleted ? 'AND p.`post_deleted` IS NULL' : ''
|
2018-10-10 11:21:57 +02:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$query = '
|
|
|
|
SELECT
|
2018-10-11 23:43:52 +02:00
|
|
|
`category_id`, `category_name`, `category_description`,
|
|
|
|
`category_is_hidden`, `category_created`
|
|
|
|
FROM `msz_news_categories`
|
|
|
|
WHERE `category_id` = :category
|
|
|
|
GROUP BY `category_id`
|
2018-10-10 11:21:57 +02:00
|
|
|
';
|
|
|
|
}
|
|
|
|
|
|
|
|
$getCategory = db_prepare($query);
|
|
|
|
$getCategory->bindValue('category', $category);
|
2019-01-09 20:06:02 +01:00
|
|
|
return db_fetch($getCategory);
|
2018-10-10 11:21:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function news_posts_count(
|
|
|
|
?int $category = null,
|
|
|
|
bool $featuredOnly = false,
|
|
|
|
bool $exposeScheduled = false,
|
|
|
|
bool $excludeDeleted = true
|
|
|
|
): int {
|
|
|
|
$hasCategory= $category !== null;
|
|
|
|
|
|
|
|
$countPosts = db_prepare(sprintf(
|
|
|
|
'
|
|
|
|
SELECT COUNT(`post_id`)
|
|
|
|
FROM `msz_news_posts`
|
|
|
|
WHERE %1$s %2$s %3$s %4$s
|
|
|
|
',
|
|
|
|
$hasCategory ? '`category_id` = :category' : '1',
|
2018-10-11 23:43:52 +02:00
|
|
|
$featuredOnly ? 'AND `post_is_featured` != 0' : '',
|
|
|
|
$exposeScheduled ? '' : 'AND `post_scheduled` < NOW()',
|
|
|
|
$excludeDeleted ? 'AND `post_deleted` IS NULL' : ''
|
2018-10-10 11:21:57 +02:00
|
|
|
));
|
|
|
|
|
|
|
|
if ($hasCategory) {
|
|
|
|
$countPosts->bindValue('category', $category);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $countPosts->execute() ? (int)$countPosts->fetchColumn() : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function news_posts_get(
|
|
|
|
int $offset,
|
|
|
|
int $take,
|
|
|
|
?int $category = null,
|
|
|
|
bool $featuredOnly = false,
|
|
|
|
bool $exposeScheduled = false,
|
|
|
|
bool $excludeDeleted = true
|
|
|
|
): array {
|
|
|
|
$getAll = $offset < 0 || $take < 1;
|
|
|
|
$hasCategory= $category !== null;
|
|
|
|
|
|
|
|
$getPosts = db_prepare(sprintf(
|
|
|
|
'
|
|
|
|
SELECT
|
2018-10-11 23:43:52 +02:00
|
|
|
p.`post_id`, p.`post_is_featured`, p.`post_title`, p.`post_text`, p.`comment_section_id`,
|
|
|
|
p.`post_created`, p.`post_updated`, p.`post_deleted`, p.`post_scheduled`,
|
2018-10-10 11:21:57 +02:00
|
|
|
c.`category_id`, c.`category_name`,
|
|
|
|
u.`user_id`, u.`username`,
|
|
|
|
COALESCE(u.`user_colour`, r.`role_colour`) as `user_colour`,
|
|
|
|
(
|
|
|
|
SELECT COUNT(`comment_id`)
|
|
|
|
FROM `msz_comments_posts`
|
|
|
|
WHERE `category_id` = `comment_section_id`
|
2018-10-14 20:11:27 +02:00
|
|
|
AND `comment_deleted` IS NULL
|
2018-10-10 11:21:57 +02:00
|
|
|
) as `post_comments`
|
|
|
|
FROM `msz_news_posts` as p
|
|
|
|
LEFT JOIN `msz_news_categories` as c
|
|
|
|
ON p.`category_id` = c.`category_id`
|
|
|
|
LEFT JOIN `msz_users` as u
|
|
|
|
ON p.`user_id` = u.`user_id`
|
|
|
|
LEFT JOIN `msz_roles` as r
|
|
|
|
ON u.`display_role` = r.`role_id`
|
|
|
|
WHERE %5$s %2$s %3$s %4$s
|
2018-10-11 23:43:52 +02:00
|
|
|
ORDER BY p.`post_created` DESC
|
2018-10-10 11:21:57 +02:00
|
|
|
%1$s
|
|
|
|
',
|
|
|
|
$getAll ? '' : 'LIMIT :offset, :take',
|
2018-10-11 23:43:52 +02:00
|
|
|
$featuredOnly ? 'AND p.`post_is_featured` != 0' : '',
|
|
|
|
$exposeScheduled ? '' : 'AND p.`post_scheduled` < NOW()',
|
|
|
|
$excludeDeleted ? 'AND p.`post_deleted` IS NULL' : '',
|
2018-10-10 11:21:57 +02:00
|
|
|
$hasCategory ? 'p.`category_id` = :category' : '1'
|
|
|
|
));
|
|
|
|
|
|
|
|
if ($hasCategory) {
|
|
|
|
$getPosts->bindValue('category', $category);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$getAll) {
|
|
|
|
$getPosts->bindValue('take', $take);
|
|
|
|
$getPosts->bindValue('offset', $offset);
|
|
|
|
}
|
|
|
|
|
2019-01-09 20:06:02 +01:00
|
|
|
return db_fetch_all($getPosts);
|
2018-10-10 11:21:57 +02:00
|
|
|
}
|
|
|
|
|
2019-05-05 16:25:21 +02:00
|
|
|
function news_posts_search(string $query): array {
|
|
|
|
$searchPosts = db_prepare('
|
|
|
|
SELECT
|
|
|
|
p.`post_id`, p.`post_is_featured`, p.`post_title`, p.`post_text`, p.`comment_section_id`,
|
|
|
|
p.`post_created`, p.`post_updated`, p.`post_deleted`, p.`post_scheduled`,
|
|
|
|
c.`category_id`, c.`category_name`,
|
|
|
|
u.`user_id`, u.`username`,
|
|
|
|
COALESCE(u.`user_colour`, r.`role_colour`) as `user_colour`,
|
|
|
|
(
|
|
|
|
SELECT COUNT(`comment_id`)
|
|
|
|
FROM `msz_comments_posts`
|
|
|
|
WHERE `category_id` = `comment_section_id`
|
|
|
|
AND `comment_deleted` IS NULL
|
|
|
|
) as `post_comments`
|
|
|
|
FROM `msz_news_posts` as p
|
|
|
|
LEFT JOIN `msz_news_categories` as c
|
|
|
|
ON p.`category_id` = c.`category_id`
|
|
|
|
LEFT JOIN `msz_users` as u
|
|
|
|
ON p.`user_id` = u.`user_id`
|
|
|
|
LEFT JOIN `msz_roles` as r
|
|
|
|
ON u.`display_role` = r.`role_id`
|
|
|
|
WHERE MATCH(`post_title`, `post_text`)
|
|
|
|
AGAINST (:query IN NATURAL LANGUAGE MODE)
|
|
|
|
AND p.`post_deleted` IS NULL
|
|
|
|
AND p.`post_scheduled` < NOW()
|
|
|
|
ORDER BY p.`post_created` DESC
|
|
|
|
');
|
|
|
|
$searchPosts->bindValue('query', $query);
|
|
|
|
|
|
|
|
return db_fetch_all($searchPosts);
|
|
|
|
}
|
|
|
|
|
2018-10-10 11:21:57 +02:00
|
|
|
function news_post_comments_set(int $postId, int $sectionId): void
|
|
|
|
{
|
|
|
|
db_prepare('
|
|
|
|
UPDATE `msz_news_posts`
|
|
|
|
SET `comment_section_id` = :comment_section_id
|
|
|
|
WHERE `post_id` = :post_id
|
|
|
|
')->execute([
|
|
|
|
'comment_section_id' => $sectionId,
|
|
|
|
'post_id' => $postId,
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
function news_post_get(int $postId): array
|
|
|
|
{
|
|
|
|
$getPost = db_prepare('
|
|
|
|
SELECT
|
2018-10-11 23:43:52 +02:00
|
|
|
p.`post_id`, p.`post_title`, p.`post_text`, p.`post_is_featured`, p.`post_scheduled`,
|
|
|
|
p.`post_created`, p.`post_updated`, p.`post_deleted`, p.`comment_section_id`,
|
2018-10-10 11:21:57 +02:00
|
|
|
c.`category_id`, c.`category_name`,
|
|
|
|
u.`user_id`, u.`username`,
|
|
|
|
COALESCE(u.`user_colour`, r.`role_colour`) as `user_colour`
|
|
|
|
FROM `msz_news_posts` as p
|
|
|
|
LEFT JOIN `msz_news_categories` as c
|
|
|
|
ON p.`category_id` = c.`category_id`
|
|
|
|
LEFT JOIN `msz_users` as u
|
|
|
|
ON p.`user_id` = u.`user_id`
|
|
|
|
LEFT JOIN `msz_roles` as r
|
|
|
|
ON u.`display_role` = r.`role_id`
|
|
|
|
WHERE `post_id` = :post_id
|
|
|
|
');
|
|
|
|
$getPost->bindValue(':post_id', $postId);
|
2019-01-09 20:06:02 +01:00
|
|
|
return db_fetch($getPost);
|
2018-10-10 11:21:57 +02:00
|
|
|
}
|
2019-04-12 23:37:59 +02:00
|
|
|
|
2019-05-28 22:07:20 +02:00
|
|
|
define('MSZ_NEWS_FEED_ATOM', 'atom');
|
|
|
|
define('MSZ_NEWS_FEED_RSS', 'rss');
|
|
|
|
define('MSZ_NEWS_SUPPORTED_FEEDS', [
|
|
|
|
MSZ_NEWS_FEED_ATOM, MSZ_NEWS_FEED_RSS,
|
|
|
|
]);
|
|
|
|
|
|
|
|
function news_feed_supported(string $type): string {
|
|
|
|
return in_array($type, MSZ_NEWS_SUPPORTED_FEEDS);
|
|
|
|
}
|
|
|
|
|
2019-04-12 23:37:59 +02:00
|
|
|
function news_feed(string $type, array $posts, array $info): string
|
|
|
|
{
|
2019-05-28 22:07:20 +02:00
|
|
|
if(!news_feed_supported($type)) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2019-04-12 23:37:59 +02:00
|
|
|
$document = new DOMDocument('1.0', 'utf-8');
|
|
|
|
$urlPrefix = url_prefix(false);
|
|
|
|
$htmlUrl = $urlPrefix . $info['html-url'];
|
|
|
|
$feedUrl = $urlPrefix . $info['feed-url'];
|
|
|
|
|
|
|
|
if ($type === 'rss') {
|
|
|
|
$dateFormat = 'r';
|
|
|
|
$rss = $document->appendChild($document->createElement('rss'));
|
|
|
|
$rss->setAttribute('version', '2.0');
|
|
|
|
$rss->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
|
|
|
|
$feed = $rss->appendChild($document->createElement('channel'));
|
|
|
|
$feed->appendChild($document->createElement('ttl', '900'));
|
|
|
|
} else {
|
|
|
|
$dateFormat = 'c';
|
|
|
|
$feed = $document->appendChild($document->createElement('feed'));
|
|
|
|
$feed->setAttribute('xmlns', 'http://www.w3.org/2005/Atom');
|
|
|
|
$link = $feed->appendChild($document->createElement('link'));
|
|
|
|
$link->setAttribute('href', $htmlUrl);
|
|
|
|
}
|
|
|
|
|
|
|
|
$feed->appendChild($document->createElement('title', $info['title']));
|
|
|
|
$feed->appendChild($document->createElement(
|
|
|
|
$type === 'rss' ? 'description' : 'subtitle', $info['subtitle']
|
|
|
|
));
|
|
|
|
$feed->appendChild($document->createElement(
|
|
|
|
$type === 'rss' ? 'link' : 'id', $htmlUrl
|
|
|
|
));
|
|
|
|
$feed->appendChild($document->createElement(
|
|
|
|
$type === 'rss' ? 'pubDate' : 'updated',
|
|
|
|
date($dateFormat, strtotime($posts[0]['post_created']))
|
|
|
|
));
|
|
|
|
$link = $feed->appendChild($document->createElement($type === 'rss' ? 'atom:link' : 'link'));
|
|
|
|
$link->setAttribute('rel', 'self');
|
|
|
|
$link->setAttribute('href', $feedUrl);
|
|
|
|
|
|
|
|
foreach ($posts as $post) {
|
|
|
|
$entry = $feed->appendChild($document->createElement($type === 'rss' ? 'item' : 'entry'));
|
|
|
|
$entry->appendChild($document->createElement('title', $post['post_title']));
|
|
|
|
$entry->appendChild($document->createElement(
|
|
|
|
$type === 'rss' ? 'link' : 'id',
|
|
|
|
$urlPrefix . url('news-post', ['post' => $post['post_id']])
|
|
|
|
));
|
|
|
|
$entry->appendChild($document->createElement(
|
|
|
|
$type === 'rss' ? 'pubDate' : 'updated',
|
|
|
|
date($dateFormat, strtotime($post['post_created']))
|
|
|
|
));
|
|
|
|
|
|
|
|
$entry->appendChild($document->createElement(
|
|
|
|
$type === 'rss' ? 'description' : 'summary',
|
|
|
|
first_paragraph($post['post_text'])
|
|
|
|
));
|
|
|
|
|
|
|
|
if ($type === 'rss') {
|
|
|
|
$entry->appendChild($document->createElement(
|
|
|
|
'comments',
|
|
|
|
$urlPrefix . url('news-post-comments', ['post' => $post['post_id']])
|
|
|
|
));
|
|
|
|
$guid = $entry->appendChild($document->createElement(
|
|
|
|
'guid',
|
|
|
|
$urlPrefix . url('news-post', ['post' => $post['post_id']])
|
|
|
|
));
|
|
|
|
$guid->setAttribute('isPermaLink', 'true');
|
|
|
|
} else {
|
|
|
|
$link = $entry->appendChild($document->createElement('link'));
|
|
|
|
$link->setAttribute('href', $urlPrefix . url('news-post', ['post' => $post['post_id']]));
|
|
|
|
$link->setAttribute('type', 'text/html');
|
|
|
|
$html = $entry->appendChild($document->createElement(
|
|
|
|
'content',
|
|
|
|
htmlentities(parse_text($post['post_text'], MSZ_PARSER_MARKDOWN))
|
|
|
|
));
|
|
|
|
$html->setAttribute('type', 'html');
|
|
|
|
$author = $entry->appendChild($document->createElement('author'));
|
|
|
|
$author->appendChild($document->createElement('name', $post['username']));
|
|
|
|
$author->appendChild($document->createElement('uri', $urlPrefix . url('user-profile', ['user' => $post['user_id']])));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $document->saveXML();
|
|
|
|
}
|