<commit_before><?php

namespace App\Controller\Admin;

use vxPHP\Util\Rex;

use vxPHP\Image\ImageModifierFactory;
use vxPHP\Template\SimpleTemplate;
use vxPHP\Controller\Controller;

use vxPHP\Form\HtmlForm;
use vxPHP\Form\FormElement\FormElementFactory;

use vxWeb\Model\MetaFile\MetaFile;
use vxWeb\Model\Article\ArticleQuery;
use vxWeb\Model\Article\Article;
use vxWeb\Model\Article\Exception\ArticleException;
use vxWeb\Model\ArticleCategory\ArticleCategory;
use vxWeb\Model\ArticleCategory\Exception\ArticleCategoryException;

use vxPHP\Http\Response;
use vxPHP\Http\JsonResponse;

use vxPHP\Application\Application;
use vxPHP\Routing\Router;
use vxPHP\Webpage\MenuGenerator;
use vxPHP\Database\Util;
use vxPHP\Constraint\Validator\Date;
use vxPHP\Application\Locale\Locale;
use vxPHP\Constraint\Validator\RegularExpression;
use vxWeb\Model\ArticleCategory\ArticleCategoryQuery;

class ArticlesController extends Controller {

	protected function execute() {

		$admin = Application::getInstance()->getCurrentUser();
		$redirectUrl = Router::getRoute('articles', 'admin.php')->getUrl();
		$action = $this->route->getPathParameter('action');
		
		if($action === 'list') {
			return $this->createArticlesList($this->request->request->get('filter'));
		}

		// editing something?

		else if(($id = $this->request->query->get('id'))) {

			try {
				$article = Article::getInstance($id);
			}
			catch(ArticleException $e) {
				return $this->redirect($redirectUrl);
			}

			// check permission of non superadmin

			if(!$admin->hasRole('superadmin') && $admin->getAttribute('id') != $article->getCreatedById()) {
				return $this->redirect($redirectUrl);
			}
		}

		// delete article

		if(isset($article) && $action === 'del') {

			try {
				$article->delete();
			}
			catch(ArticleException $e) { }

			return $this->redirect($redirectUrl);
		}

		// edit or add article

		if(isset($article) || $action === 'new') {
			
			MenuGenerator::setForceActiveMenu(TRUE);

			// fill category related properties - replacing default method allows user privilege considerations

			$articleForm = $this->buildEditForm();

			if(isset($article)) {

				$articleForm->setInitFormValues([
					'articlecategoriesid'	=> $article->getCategory()->getId(),
					'headline'				=> $article->getHeadline(),
					'customsort'			=> $article->getCustomSort(),
					'teaser'				=> $article->getData('teaser'),
					'content'				=> htmlspecialchars($article->getData('content'), ENT_NOQUOTES, 'UTF-8'),
					'article_date'			=> is_null($article->getDate())			? '' : $article->getDate()->format('d.m.Y'),
					'display_from'			=> is_null($article->getDisplayFrom())	? '' : $article->getDisplayFrom()->format('d.m.Y'),
					'display_until'			=> is_null($article->getDisplayUntil())	? '' : $article->getDisplayUntil()->format('d.m.Y')
				]);

				$submitLabel = 'Änderungen übernehmen';

			}

			else {

				$article = new Article();
				$submitLabel = 'Artikel anlegen';
				$articleForm->initVar('is_add', 1);
			}

			$articleForm->addElement(FormElementFactory::create('button', 'submit_article')->setInnerHTML($submitLabel));

			$articleForm->bindRequestParameters();

			$uploadMaxFilesize = min(
					$this->toBytes(ini_get('upload_max_filesize')),
					$this->toBytes(ini_get('post_max_size'))
			);
			$maxExecutionTime = ini_get('max_execution_time');
				
			return new Response(
				SimpleTemplate::create('admin/articles_edit.php')
					->assign('title', $article->getHeadline())
					->assign('backlink', $this->pathSegments[0])
					->assign('article_form', $articleForm->render())
					->assign('upload_max_filesize',		$uploadMaxFilesize)
					->assign('max_execution_time_ms',	$maxExecutionTime * 900) // 10pct "safety margin"
					->display()
			);
		}

		return new Response(SimpleTemplate::create('admin/articles_list.php')->display());

	}

	/**
	 * simple helper function to convert ini values like 10M or 256K to integer
	 *
	 * @param string $val
	 */
	private function toBytes($val) {

		$suffix = strtolower(substr(trim($val),-1));
		
		$val = (int) $val;
		
		switch($suffix) {
		
			case 'g':
				$val *= 1024;
			case 'm':
				$val *= 1024;
			case 'k':
				$val *= 1024;
		}
		return $val;
	}
	
	private function createArticlesList(array $filter = []) {

		$admin = Application::getInstance()->getCurrentUser();
		$db = Application::getInstance()->getDb();

		// restrict list to articles which were created by user

		$query = ArticleQuery::create($db)
			->where($admin->hasRole('superadmin') ? '1 = 1' : ('createdBy = ' . (int) $admin->getAttribute('id')))
			->sortBy('lastUpdated', FALSE)
		;
			
		// apply filter for title

		if(isset($filter['title']) && trim($filter['title'])) {

			$query->where('headline LIKE ?', ['%' . trim($filter['title']) . '%']);

		}
		
		// apply filter for a category name
		
		if(isset($filter['category']) && trim($filter['category'])) {
			
			$categories = ArticleCategoryQuery::create($db)->where('title LIKE ?', ['%' . trim($filter['category']) . '%'])->select();

			if(count($categories)) {
				$query->filterByCategories($categories);
			}
			
		}<commit_msg>Preparatory work for article sorting in article controller<commit_after><?php

namespace App\Controller\Admin;

use vxPHP\Util\Rex;

use vxPHP\Image\ImageModifierFactory;
use vxPHP\Template\SimpleTemplate;
use vxPHP\Controller\Controller;

use vxPHP\Form\HtmlForm;
use vxPHP\Form\FormElement\FormElementFactory;

use vxWeb\Model\MetaFile\MetaFile;
use vxWeb\Model\Article\ArticleQuery;
use vxWeb\Model\Article\Article;
use vxWeb\Model\Article\Exception\ArticleException;
use vxWeb\Model\ArticleCategory\ArticleCategory;
use vxWeb\Model\ArticleCategory\Exception\ArticleCategoryException;

use vxPHP\Http\Response;
use vxPHP\Http\JsonResponse;

use vxPHP\Application\Application;
use vxPHP\Routing\Router;
use vxPHP\Webpage\MenuGenerator;
use vxPHP\Database\Util;
use vxPHP\Constraint\Validator\Date;
use vxPHP\Application\Locale\Locale;
use vxPHP\Constraint\Validator\RegularExpression;
use vxWeb\Model\ArticleCategory\ArticleCategoryQuery;

class ArticlesController extends Controller {

	protected function execute() {

		$admin = Application::getInstance()->getCurrentUser();
		$redirectUrl = Router::getRoute('articles', 'admin.php')->getUrl();
		$action = $this->route->getPathParameter('action');
		
		if($action === 'list') {
			return $this->createArticlesList($this->request->request->get('filter'));
		}

		// editing something?

		else if(($id = $this->request->query->get('id'))) {

			try {
				$article = Article::getInstance($id);
			}
			catch(ArticleException $e) {
				return $this->redirect($redirectUrl);
			}

			// check permission of non superadmin

			if(!$admin->hasRole('superadmin') && $admin->getAttribute('id') != $article->getCreatedById()) {
				return $this->redirect($redirectUrl);
			}
		}

		// delete article

		if(isset($article) && $action === 'del') {

			try {
				$article->delete();
			}
			catch(ArticleException $e) { }

			return $this->redirect($redirectUrl);
		}

		// edit or add article

		if(isset($article) || $action === 'new') {
			
			MenuGenerator::setForceActiveMenu(TRUE);

			// fill category related properties - replacing default method allows user privilege considerations

			$articleForm = $this->buildEditForm();

			if(isset($article)) {

				$articleForm->setInitFormValues([
					'articlecategoriesid'	=> $article->getCategory()->getId(),
					'headline'				=> $article->getHeadline(),
					'customsort'			=> $article->getCustomSort(),
					'teaser'				=> $article->getData('teaser'),
					'content'				=> htmlspecialchars($article->getData('content'), ENT_NOQUOTES, 'UTF-8'),
					'article_date'			=> is_null($article->getDate())			? '' : $article->getDate()->format('d.m.Y'),
					'display_from'			=> is_null($article->getDisplayFrom())	? '' : $article->getDisplayFrom()->format('d.m.Y'),
					'display_until'			=> is_null($article->getDisplayUntil())	? '' : $article->getDisplayUntil()->format('d.m.Y')
				]);

				$submitLabel = 'Änderungen übernehmen';

			}

			else {

				$article = new Article();
				$submitLabel = 'Artikel anlegen';
				$articleForm->initVar('is_add', 1);
			}

			$articleForm->addElement(FormElementFactory::create('button', 'submit_article')->setInnerHTML($submitLabel));

			$articleForm->bindRequestParameters();

			$uploadMaxFilesize = min(
					$this->toBytes(ini_get('upload_max_filesize')),
					$this->toBytes(ini_get('post_max_size'))
			);
			$maxExecutionTime = ini_get('max_execution_time');
				
			return new Response(
				SimpleTemplate::create('admin/articles_edit.php')
					->assign('title', $article->getHeadline())
					->assign('backlink', $this->pathSegments[0])
					->assign('article_form', $articleForm->render())
					->assign('upload_max_filesize',		$uploadMaxFilesize)
					->assign('max_execution_time_ms',	$maxExecutionTime * 900) // 10pct "safety margin"
					->display()
			);
		}

		return new Response(SimpleTemplate::create('admin/articles_list.php')->display());

	}

	/**
	 * simple helper function to convert ini values like 10M or 256K to integer
	 *
	 * @param string $val
	 */
	private function toBytes($val) {

		$suffix = strtolower(substr(trim($val),-1));
		
		$val = (int) $val;
		
		switch($suffix) {
		
			case 'g':
				$val *= 1024;
			case 'm':
				$val *= 1024;
			case 'k':
				$val *= 1024;
		}
		return $val;
	}
	
	private function createArticlesList(array $filter = [], array $sort = NULL) {

		$admin = Application::getInstance()->getCurrentUser();
		$db = Application::getInstance()->getDb();

		// restrict list to articles which were created by user

		$query = ArticleQuery::create($db)
			->where($admin->hasRole('superadmin') ? '1 = 1' : ('createdBy = ' . (int) $admin->getAttribute('id')))
		;

		// add sorting

		if($sort) {
			if($sort['column'] !== 'category') {
				$query->$sortBy($sort['column'], $sort['asc']);
			}
			else {
			}
		}
		else {
			$query->sortBy('lastUpdated', FALSE);
		}
		
		// apply filter for title

		if(isset($filter['title']) && trim($filter['title'])) {

			$query->where('headline LIKE ?', ['%' . trim($filter['title']) . '%']);

		}
		
		// apply filter for a category name
		
		if(isset($filter['category']) && trim($filter['category'])) {
			
			$categories = ArticleCategoryQuery::create($db)->where('title LIKE ?', ['%' . trim($filter['category']) . '%'])->select();

			if(count($categories)) {
				$query->filterByCategories($categories);
			}
			
		}
{'fraction_non_alphanumeric': 0.17759954167860212, 'fraction_numerical': 0.005347082975269741, 'mean_word_length': 4.198014888337469, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 142, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1358882', 'n_tokens_mistral': 3967, 'n_tokens_neox': 3275, 'n_words': 569}