/** * Register the article's metadata with the SWORD deposit. */ function setMetadata() { $this->package->setCustodian($this->journal->getSetting('contactName')); $this->package->setTitle(html_entity_decode($this->article->getTitle($this->journal->getPrimaryLocale()), ENT_QUOTES, 'UTF-8')); $this->package->setAbstract(html_entity_decode(strip_tags($this->article->getAbstract($this->journal->getPrimaryLocale())), ENT_QUOTES, 'UTF-8')); $this->package->setType($this->section->getIdentifyType($this->journal->getPrimaryLocale())); // The article can be published or not. Support either. if (is_a($this->article, 'PublishedArticle')) { $doi = $this->article->getPubId('doi'); if ($doi !== null) { $this->package->setIdentifier($doi); } } foreach ($this->article->getAuthors() as $author) { $creator = $author->getFullName(true); $affiliation = $author->getAffiliation($this->journal->getPrimaryLocale()); if (!empty($affiliation)) { $creator .= "; {$affiliation}"; } $this->package->addCreator($creator); } // The article can be published or not. Support either. if (is_a($this->article, 'PublishedArticle')) { $plugin = PluginRegistry::loadPlugin('citationFormats', 'bibtex'); $this->package->setCitation(html_entity_decode(strip_tags($plugin->fetchCitation($this->article, $this->issue, $this->journal)), ENT_QUOTES, 'UTF-8')); } }
/** * Create a new poll * @param wgRequest question * @param wgRequest answer (expects PHP array style in the form <input name=answer[]>) * Page Content should be of a different style so we have to translate * *question 1\n * *question 2\n */ public static function create() { wfProfileIn(__METHOD__); $app = F::app(); $title = $app->wg->Request->getVal('question'); $answers = $app->wg->Request->getArray('answer'); // array $title_object = Title::newFromText($title, NS_WIKIA_POLL); if (is_object($title_object) && $title_object->exists()) { $res = array('success' => false, 'error' => $app->renderView('Error', 'Index', array(wfMsg('wikiapoll-error-duplicate')))); } else { if ($title_object == null) { $res = array('success' => false, 'error' => $app->renderView('Error', 'Index', array(wfMsg('wikiapoll-error-invalid-title')))); } else { $content = ""; foreach ($answers as $answer) { $content .= "*{$answer}\n"; } /* @var $article WikiPage */ $article = new Article($title_object, NS_WIKIA_POLL); $article->doEdit($content, 'Poll Created', EDIT_NEW, false, $app->wg->User); $title_object = $article->getTitle(); // fixme: check status object $res = array('success' => true, 'pollId' => $article->getID(), 'url' => $title_object->getLocalUrl(), 'question' => $title_object->getPrefixedText()); } } wfProfileOut(__METHOD__); return $res; }
/** * Log article related event. * * @param Article $p_article * @param string $p_text * @param int $p_userId * @param int $p_eventId * @param bool $p_short * * @return void */ public static function ArticleMessage(Article $p_article, $p_text, $p_userId = NULL, $p_eventId = 0, $p_short = FALSE) { ob_start(); $translator = \Zend_Registry::get('container')->getService('translator'); echo $translator->trans('Article'), ': ', $p_article->getTitle(); if (!$p_short) { // add publication, issue, section echo ' ('; echo $translator->trans('Publication'), ': ', $p_article->getPublicationId(); echo ', '; echo $translator->trans('Issue'), ': ', $p_article->getIssueNumber(); echo ', '; echo $translator->trans('Section'), ': ', $p_article->getSectionNumber(); echo ")\n"; } // generate url $url = ShortURL::GetURL($p_article->getPublicationId(), $p_article->getLanguageId(), $p_article->getIssueNumber(), $p_article->getSectionNumber(), $p_article->getArticleNumber()); if (strpos($url, 'http') !== FALSE) { // no url for deleted echo $translator->trans('Article URL', array(), 'api'), ': ', $url, "\n"; } echo $translator->trans('Article Number', array(), 'api'), ': ', $p_article->getArticleNumber(), "\n"; echo $translator->trans('Language'), ': ', $p_article->getLanguageName(), "\n"; echo "\n"; echo $translator->trans('Action') . ': ', $p_text; $message = ob_get_clean(); self::Message(substr($message, 0, 254), $p_userId, $p_eventId); }
/** * Create category. * * @param $category String: Name of category to create. * @param $code String: Code of language that the category is for. * @param $level String: Level that the category is for. */ public static function create($category, $code, $level = null) { $category = strip_tags($category); $title = Title::makeTitleSafe(NS_CATEGORY, $category); if ($title === null || $title->exists()) { return; } global $wgLanguageCode; $language = BabelLanguageCodes::getName($code, $wgLanguageCode); if ($level === null) { $text = wfMsgForContent('babel-autocreate-text-main', $language, $code); } else { $text = wfMsgForContent('babel-autocreate-text-levels', $level, $language, $code); } $user = self::user(); # Do not add a message if the username is invalid or if the account that adds it, is blocked if (!$user || $user->isBlocked()) { return; } $article = new Article($title, 0); if (!$article->getTitle()->quickUserCan('create', $user)) { return; # The Babel AutoCreate account is not allowed to create the page } /* $article->doEdit will call $wgParser->parse. * Calling Parser::parse recursively is baaaadd... (bug 29245) * @todo FIXME: surely there is a better way? */ global $wgParser, $wgParserConf; $oldParser = $wgParser; $parserClass = $wgParserConf['class']; $wgParser = new $parserClass($wgParserConf); $article->doEdit($text, wfMsgForContent('babel-autocreate-reason', wfMsgForContent('babel-url')), EDIT_FORCE_BOT, false, $user); $wgParser = $oldParser; }
/** * Hook entry when article is change * * @param Article $article */ public static function onArticleSaveComplete(&$article, &$user, $text, $summary, $minoredit, $watchthis, $sectionanchor, &$flags, $revision, &$status, $baseRevId, &$redirect) { $title = $article->getTitle(); $ce = new CategoryExhibitionSection(null); $ce->setTouched($title); return true; }
public static function onArticleViewAfterParser(Article $article, ParserOutput $parserOutput) { global $wgCityId, $wgDBname; // we collect production data from Oasis only /* $app = F::app(); if ( !$app->checkSkin( 'oasis', $app->wg->Skin ) || $app->wg->DevelEnvironment || $app->wg->StagingEnvironment ) { return true; } */ if (class_exists('WScribeClient')) { try { $title = $article->getTitle(); $fields = array('wikiId' => intval($wgCityId), 'databaseName' => $wgDBname, 'articleId' => $title->getArticleID(), 'namespaceId' => $title->getNamespace(), 'articleTitle' => $title->getText(), 'parserTime' => $parserOutput->getPerformanceStats('time'), 'wikitextSize' => $parserOutput->getPerformanceStats('wikitextSize'), 'htmlSize' => $parserOutput->getPerformanceStats('htmlSize'), 'expFuncCount' => $parserOutput->getPerformanceStats('expFuncCount'), 'nodeCount' => $parserOutput->getPerformanceStats('nodeCount'), 'postExpandSize' => $parserOutput->getPerformanceStats('postExpandSize'), 'tempArgSize' => $parserOutput->getPerformanceStats('tempArgSize')); $data = json_encode($fields); WScribeClient::singleton(self::SCRIBE_KEY)->send($data); } catch (TException $e) { Wikia::log(__METHOD__, 'scribeClient exception', $e->getMessage()); } } // Logging parser activity for monitoring // wiki and article info are sent to logstash anyways so no need to repeat them here WikiaLogger::instance()->info("Parser execution", ['parser-time' => round($parserOutput->getPerformanceStats('time') * 1000), 'node-count' => (int) $parserOutput->getPerformanceStats('nodeCount'), 'wikitext-size' => (int) $parserOutput->getPerformanceStats('wikitextSize'), 'skin-name' => RequestContext::getMain()->getSkin()->getSkinName()]); return true; }
/** * */ public function getSimpleFormatForArticle(\Article $article) { $measurement = \Wikia\Measurements\Time::start([__CLASS__, __METHOD__]); $cacheKey = wfMemcKey("SimpleJson", $article->getPage()->getId(), self::SIMPLE_JSON_SCHEMA_VERSION); $jsonSimple = $this->app->wg->memc->get($cacheKey); if ($jsonSimple === false) { /** * Prevention from circular references, when parsing articles with tabs. * * E.g. when page contains tab, which is actually link to itself, * or if any tab contains tab, which referenced to given page. * * @see DivContainingHeadersVisitor::parseTabview */ \Wikia\JsonFormat\HtmlParser::markAsVisited($article->getTitle()->getText()); $jsonFormatRootNode = $this->getJsonFormatForArticle($article); // We have finished parsing of article, so we can clean array of visited articles \Wikia\JsonFormat\HtmlParser::clearVisited(); $simplifier = new Wikia\JsonFormat\JsonFormatSimplifier(); $jsonSimple = $simplifier->simplify($jsonFormatRootNode, $article->getTitle()->getText()); $this->app->wg->memc->set($cacheKey, $jsonSimple, self::SIMPLE_JSON_CACHE_EXPIRATION); } $measurement->stop(); return $jsonSimple; }
protected function loadOne($file) { $xml = new SimpleXMLElement($file, 0, true); if ((string) $xml->head->title == null) { return null; } $article = new Article(); foreach ($xml->head->meta as $meta) { $name = (string) $meta['name']; $content = (string) $meta['content']; switch ($name) { case 'date': $article->setPublicationDate(new DateTime($content)); break; case 'author': $article->setAuthor($content); break; } } $article->setTitle((string) $xml->head->title); $article->setHash($this->getHash($article->getTitle())); $content = ""; foreach ($xml->body->children() as $child) { $content .= $child->asXml(); } $article->setContent($content); return $article; }
/** * @static * @param string $action * @param Article $article * @return bool * @throws UserBlockedError * @throws PermissionsError */ static function onPowerDelete($action, $article) { global $wgOut, $wgUser, $wgRequest; if ($action !== 'powerdelete') { return true; } if (!$wgUser->isAllowed('delete') || !$wgUser->isAllowed('powerdelete')) { throw new PermissionsError('powerdelete'); } if ($wgUser->isBlocked()) { throw new UserBlockedError($wgUser->mBlock); } if (wfReadOnly()) { $wgOut->readOnlyPage(); return false; } $reason = $wgRequest->getText('reason'); $title = $article->getTitle(); $file = $title->getNamespace() == NS_IMAGE ? wfLocalFile($title) : false; if ($file) { $oldimage = null; FileDeleteForm::doDelete($title, $file, $oldimage, $reason, false); } else { $article->doDelete($reason); } // this is stupid, but otherwise, WikiPage::doUpdateRestrictions complains about passing by reference $false = false; $article->doUpdateRestrictions(array('create' => 'sysop'), array('create' => 'infinity'), $false, $reason, $wgUser); return false; }
/** * Log article related event. * * @param Article $p_article * @param string $p_text * @param int $p_userId * @param int $p_eventId * @param bool $p_short * * @return void */ public static function ArticleMessage(Article $p_article, $p_text, $p_userId = NULL, $p_eventId = 0, $p_short = FALSE) { ob_start(); echo getGS('Article'), ': ', $p_article->getTitle(); if (!$p_short) { // add publication, issue, section echo ' ('; echo getGS('Publication'), ': ', $p_article->getPublicationId(); echo ', '; echo getGS('Issue'), ': ', $p_article->getIssueNumber(); echo ', '; echo getGS('Section'), ': ', $p_article->getSectionNumber(); echo ")\n"; } // generate url $url = ShortURL::GetURL($p_article->getPublicationId(), $p_article->getLanguageId(), $p_article->getIssueNumber(), $p_article->getSectionNumber(), $p_article->getArticleNumber()); if (strpos($url, 'http') !== FALSE) { // no url for deleted echo getGS('Article URL'), ': ', $url, "\n"; } echo getGS('Article Number'), ': ', $p_article->getArticleNumber(), "\n"; echo getGS('Language'), ': ', $p_article->getLanguageName(), "\n"; echo "\n"; echo getGS('Action') . ': ', $p_text; $message = ob_get_clean(); self::Message($message, $p_userId, $p_eventId); }
public function assertArticle(Article $article, $hash, $title, $author, $publicationDate, $content) { $this->assertEquals($article->getHash(), $hash); $this->assertEquals($article->getTitle(), $title); $this->assertEquals($article->getAuthor(), $author); $this->assertEquals($article->getPublicationDate(), $publicationDate); $this->assertEquals($article->getContent(), $content); }
/** * Instantiate this topic with a supplied Article instance. * * @param Article $article */ public function __construct(Article &$article) { $this->pArticle = $article; $this->pTitle = $article->getTitle(); if (preg_match('/' . PONYDOCS_DOCUMENTATION_NAMESPACE_NAME . ':.*:.*:.*:.*/i', $this->pTitle->__toString())) { $this->mIsDocumentationTopic = TRUE; } }
/** * ArticleSaveComplete hook * * @param Article $article */ public static function clearBlacklist(&$article, &$user, $text, $summary, $isminor, $iswatch, $section) { $title = $article->getTitle(); if ($title->getNamespace() == NS_MEDIAWIKI && $title->getDBkey() == 'Emailblacklist') { EmailBlacklist::singleton()->invalidate(); } return true; }
public function __invoke($args) { if (count($args) < 1) { throw new OrongoScriptParseException("Argument missing for Articles.GetTitle()"); } $article = new Article($args[0]); return new OrongoVariable($article->getTitle()); }
/** * @desc Process Artist article page * * @param Article $article * * @return array */ public function processArticle(Article $article) { $name = $article->getTitle()->getText(); $artistData = ['article_id' => $article->getId(), 'name' => $name, 'name_lowercase' => LyricsUtils::lowercase($name)]; $artistData = array_merge($artistData, $this->getHeader($article)); $artistData = array_merge($artistData, $this->getFooter($article)); $artistData['genres'] = $this->getGenres($article); return $this->sanitizeData($artistData, $this->getDataMap()); }
/** * Article::view() hook * * @param Article $article * @return bool */ public static function viewHook($article) { global $wgOut; $title = $article->getTitle(); if (MWNamespace::isContent($title->getNamespace())) { $wgOut->addHTML(self::buildLinks($title)); $wgOut->addHeadItem('backandforth', self::buildHeadItem()); } return true; }
public static function addMessageWall($userPageTitle) { wfProfileIn(__METHOD__); $botUser = User::newFromName('WikiaBot'); $article = new Article($userPageTitle); $status = $article->doEdit('', '', EDIT_NEW | EDIT_MINOR | EDIT_SUPPRESS_RC | EDIT_FORCE_BOT, false, $botUser); $title = $status->isOK() ? $article->getTitle() : false; wfProfileOut(__METHOD__); return $title; }
/** * Handles the custom action * * @param string $action * @param Article $article */ function efCustomActionHandler($action, $article) { global $wgOut; if ($action == 'code') { $wgOut->setPageTitle($article->getTitle()->getText()); #$wgOut->addWikiText( "You are performing a custom action on '''" . $article->getTitle()->getText() . "'''." ); $wgOut->addHTML(git_render_page()); } return false; }
/** * * Whether the article object in this category. * @param Article $article An article Object * @param string $category string */ public static function inCategory(&$article, $category) { $c = self::normalizePageTitle($category, true, NS_CATEGORY); $cs = self::getPageCategory($article->getTitle()->getArticleID()); if (in_array($c, $cs)) { return true; } else { return false; } }
/** * Gets the content of the article with the provided page name, * or an empty string when there is no such article. * * @since 0.1 * * @param string $pageName * * @return string */ public static function getParsedArticleContent($pageName) { $title = Title::newFromText($pageName); if (is_null($title)) { return ''; } $article = new Article($title, 0); global $wgParser, $wgContestEmailParse; $wgContestEmailParse = true; $text = $wgParser->parse($article->fetchContent(), $article->getTitle(), $article->getParserOptions())->getText(); $wgContestEmailParse = false; return $text; }
/** * Display a message * * @param Article &$article * @param boolean $outputDone * @param boolean $useParserCache * * @return true */ public static function onArticleViewHeader(Article &$article, &$outputDone, &$useParserCache) { global $wgOut; $title = $article->getTitle(); if (!ApprovedRevs::isAssignedToProject($title)) { return true; } $user = $article->getContext()->getUser(); $banner = self::showProjectBanner($title, $user); if (!is_null($banner)) { $wgOut->addModuleStyles('ext.wrApprovedRevs.main'); $wgOut->addHTML($banner); } return true; }
function __construct(Article $article) { // Set instance variables. $this->mArticle = $article; $this->mTitle = $article->getTitle(); $this->mApplicableTypes = $this->mTitle->getRestrictionTypes(); $this->mContext = $article->getContext(); // Check if the form should be disabled. // If it is, the form will be available in read-only to show levels. $this->mPermErrors = $this->mTitle->getUserPermissionsErrors('protect', $this->mContext->getUser(), $this->mContext->getRequest()->wasPosted() ? 'secure' : 'full'); if (wfReadOnly()) { $this->mPermErrors[] = ['readonlytext', wfReadOnlyReason()]; } $this->disabled = $this->mPermErrors != []; $this->disabledAttrib = $this->disabled ? ['disabled' => 'disabled'] : []; $this->loadData(); }
/** * Decide whether to bother showing the wikitext editor at all. * If not, we expect the VE initialisation JS to activate. * @param $article Article * @param $user User * @return bool Whether to show the wikitext editor or not. */ public static function onCustomEditor(Article $article, User $user) { $req = RequestContext::getMain()->getRequest(); $veConfig = ConfigFactory::getDefaultInstance()->makeConfig('visualeditor'); if (!$user->getOption('visualeditor-enable') || $user->getOption('visualeditor-betatempdisable') || $user->getOption('visualeditor-autodisable') || $user->getOption('visualeditor-tabs') === 'prefer-wt' || $veConfig->get('VisualEditorDisableForAnons') && $user->isAnon() || false) { return true; } $title = $article->getTitle(); $availableNamespaces = $veConfig->get('VisualEditorAvailableNamespaces'); $params = $req->getValueNames(); if ($user->isAnon()) { $editor = $req->getCookie('VEE', '', User::getDefaultOption('visualeditor-editor')); } else { $editor = $user->getOption('visualeditor-editor'); } return $req->getVal('action') !== 'edit' || !$veConfig->get('VisualEditorUseSingleEditTab') || $editor === 'wikitext' || !$title->inNamespaces(array_keys(array_filter($availableNamespaces))) || $title->getContentModel() !== CONTENT_MODEL_WIKITEXT || in_array('undo', $params) || in_array('undoafter', $params) || in_array('editintro', $params) || in_array('preload', $params) || in_array('preloadtitle', $params) || in_array('preloadparams', $params); // Known-good parameters: edit, veaction, section, vesection, veswitched }
/** * {@inheritdoc} */ public function add(Article $article) { $id = $article->getIdentifier(); $params = [':title' => $article->getTitle(), ':body' => $article->getBody(), ':year' => $article->getYear()]; $bind = [':year' => \PDO::PARAM_INT]; if ($id) { $sql = 'UPDATE ' . self::TABLE . ' SET title = :title, body = :body, publish_year = :year WHERE id = :id'; $params[':id'] = $id; $bind[':id'] = \PDO::PARAM_INT; } else { $sql = 'INSERT INTO ' . self::TABLE . ' (title, body, publish_year) VALUES (:title, :body, :year)'; } $stm = $this->conn->prepare($sql); foreach ($params as $name => $val) { $stm->bindValue($name, $val, isset($bind[$name]) ? $bind[$name] : \PDO::PARAM_STR); } $stm->execute(); return $id ? $id : intval($this->conn->lastInsertId()); }
/** * The function called if we're in index.php (as opposed to one of the * special pages) * * @since 0.1 */ public static function displayPushPage(Article $article) { global $wgOut, $wgUser, $wgTitle, $wgSitename, $egPushTargets; $wgOut->setPageTitle(wfMsgExt('push-tab-title', 'parsemag', $article->getTitle()->getText())); if (!$wgUser->isAllowed('push')) { $wgOut->permissionRequired('push'); return false; } $wgOut->addHTML('<p>' . htmlspecialchars(wfMsg('push-tab-desc')) . '</p>'); if (count($egPushTargets) == 0) { $wgOut->addHTML('<p>' . htmlspecialchars(wfMsg('push-tab-no-targets')) . '</p>'); return false; } self::loadJs(); $wgOut->addHTML(Html::hidden('pageName', $wgTitle->getFullText(), array('id' => 'pageName')) . Html::hidden('siteName', $wgSitename, array('id' => 'siteName'))); self::displayPushList(); self::displayPushOptions(); return false; }
/** * Adds handling for the tabs 'generatepages' and 'editschema'. */ public static function onUnknownAction($action, Article $article) { $title = $article->getTitle(); // These tabs should only exist for category pages if ($title->getNamespace() != NS_CATEGORY) { return true; } $categoryName = $title->getText(); if ($action == 'generatepages') { $generatePagesPage = new PSGeneratePages(); $generatePagesPage->execute($categoryName); return false; } elseif ($action == 'editschema') { $editSchemaPage = new PSEditSchema(); $editSchemaPage->execute($categoryName); return false; } return true; }
function convert($source, $target, $startdate) { $date = getdate(strtotime($startdate)); $month = $date['mon']; $day = $date['mday']; $year = $date['year']; //$date = "$month-$day-$year"; $search = $source; $pages = PrefixSearch::titleSearch($search, '10000'); $count = 0; foreach ($pages as $page) { $article = new Article(Title::newFromText($page)); $title = $article->getTitle()->getText(); $body = $article->fetchContent(0, false, false); $titles .= $this->create_event($title, $body, $target); $count++; } return $titles; //return "$count records converted!"; }
/** * Hook to insert things into article headers. * * @since 0.1 * * @param Article &$article * @param boolean $outputDone * @param boolean $useParserCache * * @return true */ public static function onArticleViewHeader(Article &$article, &$outputDone, &$useParserCache) { global $egLiveTranslateLanguages; $title = $article->getTitle(); $currentLang = LiveTranslateFunctions::getCurrentLang($title); if (in_array($title->getFullText(), LiveTranslateFunctions::getLocalMemoryNames())) { self::displayDictionaryPage($article, $title); $outputDone = true; // The translations themselves should not be shown. } elseif (LiveTranslateFunctions::hasTranslationService() && $article->exists() && (count($egLiveTranslateLanguages) > 1 || count($egLiveTranslateLanguages) == 1 && $egLiveTranslateLanguages[0] != $currentLang)) { global $wgParser; $po = $wgParser->getOutput(); $magicWords = isset($po->mLTMagicWords) ? $po->mLTMagicWords : array(); if (!in_array('LT_NOTRANSLATIONCONTROL', $magicWords)) { global $egLTNSWithTranslationControl, $egLTUnknownNSShowControl; $ns = $title->getNamespace(); if (in_array('LT_SHOWTRANSLATIONCONTROL', $magicWords) || array_key_exists($ns, $egLTNSWithTranslationControl) && $egLTNSWithTranslationControl[$ns] || !array_key_exists($ns, $egLTNSWithTranslationControl) && $egLTUnknownNSShowControl) { self::displayTranslationControl($currentLang); } } } return true; }
/** To bypass the parser cache just for the LiquidThreads part, we have a cute trick. * We leave a placeholder comment in the HTML, which we expand out in a hook. This way, * most of the page can be cached, but the LiquidThreads dynamism still works. * Thanks to Tim for the idea. */ static function lqtTalkPage($parser, $args, $parser, $frame) { $pout = $parser->getOutput(); // Prepare information. $title = null; if (!empty($args['talkpage'])) { $title = Title::newFromText($args['talkpage']); } if (is_null($title)) { $title = $parser->getTitle(); } $talkpage = new Article($title, 0); $article = new Article($parser->getTitle(), 0); $data = array('type' => 'talkpage', 'args' => $args, 'article' => $article, 'title' => $article->getTitle(), 'talkpage' => $talkpage); if (!isset($pout->mLqtReplacements)) { $pout->mLqtReplacements = array(); } // Generate a token $tok = wfGenerateToken(); $text = '<!--LQT-PAGE-' . $tok . '-->'; $pout->mLqtReplacements[$text] = $data; return $text; }
public function create($title, $content, $image, $idAuthor) { $article = new Article($this->db); try { $article->setTitle($title); $article->setContent($content); $article->setImage($image); $article->setIdAuthor($idAuthor); } catch (Exception $e) { $errors = $e->getMessage(); echo $errors; } if (!isset($err)) { $title = $this->db->quote($article->getTitle()); $content = $this->db->quote($article->getContent()); $idAuthor = $article->getIdAuthor(); if ($image == "") { $query = 'INSERT INTO article(title, content, idAuthor) VALUE (' . $title . ',' . $content . ',' . $idAuthor . ')'; } else { $image = $this->db->quote($article->getImage()); $query = 'INSERT INTO article(title, content, image, idAuthor) VALUE (' . $title . ',' . $content . ',' . $image . ',' . $idAuthor . ')'; } } $res = $this->db->exec($query); if ($res) { $id = $this->db->lastInsertId(); if ($id) { return $this->findById($id); } else { throw new Exception('Database error'); } } else { throw new Exception($errors); } }