<commit_before><?php
namespace wcf\acp\form;
use wcf\data\object\type\ObjectType;
use wcf\data\object\type\ObjectTypeCache;
use wcf\form\AbstractForm;
use wcf\system\exception\IllegalLinkException;
use wcf\system\exception\UserInputException;
use wcf\system\WCF;

/**
 * Abstract implementation of a form for bulk processing objects of a certain type.
 * 
 * @author	<NAME>
 * @copyright	2001-2017 WoltLab GmbH
 * @license	GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 * @package	WoltLabSuite\Core\Acp\Form
 * @since	3.0
 */
abstract class AbstractBulkProcessingForm extends AbstractForm {
	/**
	 * object action object type types
	 * @var	ObjectType[]
	 */
	public $actions = [];
	
	/**
	 * number of objects affected by bulk processing
	 * @var	integer
	 */
	public $affectedObjectCount = 0;
	
	/**
	 * object condition object type types
	 * @var	ObjectType[][]
	 */
	public $conditions = [];
	
	/**
	 * list with bulk processed objects
	 * @var	\wcf\data\DatabaseObjectList
	 */
	public $objectList = null;
	
	/**
	 * bulk processable object type
	 * @var	ObjectType
	 */
	public $objectType = null;
	
	/**
	 * name of the bulk processable object type
	 * @var	string
	 */
	public $objectTypeName = '';
	
	/**
	 * @inheritDoc
	 */
	public $templateName = 'bulkProcessing';
	
	/**
	 * @inheritDoc
	 */
	public function assignVariables() {
		parent::assignVariables();
		
		$classParts = explode('\\', get_class($this));
		
		WCF::getTPL()->assign([
			'actions' => $this->actions,
			'affectedObjectCount' => $this->affectedObjectCount,
			'controller' => str_replace('Form', '', array_pop($classParts)),
			'controllerApplication' => $classParts[0],
			'conditions' => $this->conditions,
			'objectType' => $this->objectType
		]);
	}
	
	/**
	 * @inheritDoc
	 */
	public function readData() {
		// read bulk processable object type
		$this->objectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.bulkProcessableObject', $this->objectTypeName);
		if ($this->objectType === null) {
			throw new \LogicException("Unknown bulk processable object type '".$this->objectTypeName."'");
		}
		
		// read conditions
		if (ObjectTypeCache::getInstance()->getDefinitionByName($this->objectType->getProcessor()->getConditionObjectTypeDefinition()) === null) {
			throw new \LogicException("Unknown condition object type definition '".$this->objectType->getProcessor()->getConditionObjectTypeDefinition()."'");
		}
		$conditionObjectTypes = ObjectTypeCache::getInstance()->getObjectTypes($this->objectType->getProcessor()->getConditionObjectTypeDefinition());
		if (empty($conditionObjectTypes)) {
			throw new IllegalLinkException();
		}
		
		foreach ($conditionObjectTypes as $objectType) {
			if ($objectType->conditiongroup) {
				if (!isset($this->conditions[$objectType->conditiongroup])) {
					$this->conditions[$objectType->conditiongroup] = [];
				}
				
				$this->conditions[$objectType->conditiongroup][$objectType->objectTypeID] = $objectType;
			}
			else {
				$this->conditions[''][$objectType->objectTypeID] = $objectType;
			}
		}
		
		// read actions
		if (ObjectTypeCache::getInstance()->getDefinitionByName($this->objectType->getProcessor()->getActionObjectTypeDefinition()) === null) {
			throw new \LogicException("Unknown action object type definition '".$this->objectType->getProcessor()->getActionObjectTypeDefinition()."'");
		}
		
		$actions = ObjectTypeCache::getInstance()->getObjectTypes($this->objectType->getProcessor()->getActionObjectTypeDefinition());
		foreach ($actions as $objectType) {
			if (isset($this->actions[$objectType->action])) {
				throw new \LogicException("Duplicate action with name '".$objectType->action."'");
			}
			
			if ($objectType->validateOptions() && $objectType->validatePermissions()) {
				$this->actions[$objectType->action] = $objectType;
			}
		}
		if (empty($this->actions)) {
			throw new IllegalLinkException();
		}
		
		parent::readData();
	}
	
	/**
	 * @inheritDoc
	 */
	public function readFormParameters() {
		parent::readFormParameters();
		
		foreach ($this->conditions as $groupedObjectTypes) {
			foreach ($groupedObjectTypes as $objectType) {
				$objectType->getProcessor()->readFormParameters();
			}
		}
		
		if (isset($this->actions[$this->action])) {
			$this->actions[$this->action]->getProcessor()->readFormParameters();
		}
	}
	
	/**
	 * @inheritDoc
	 */
	public function save() {
		$this->objectList = $this->actions[$this->action]->getProcessor()->getObjectList();
		
		parent::save();
		
		// read objects
		foreach ($this->conditions as $groupedObjectTypes) {
			foreach ($groupedObjectTypes as $objectType) {
				$data = $objectType->getProcessor()->getData();
				if ($data !== null) {
					$objectType->getProcessor()->addObjectListCondition($this->objectList, $data);
				}
			}
		}
		$this->objectList->readObjects();
		
		// execute action
		$this->actions[$this->action]->getProcessor()->executeAction($this->objectList);
		
		$this->affectedObjectCount = count($this->objectList);
		
		$this->saved();
		
		// reset fields
		$this->actions[$this->action]->getProcessor()->reset();
		
		foreach ($this->conditions as $groupedObjectTypes) {
			foreach ($groupedObjectTypes as $objectType) {
				$objectType->getProcessor()->reset();
			}
		}
		$this->action = '';
		
		WCF::getTPL()->assign('success', true);
	}
	
	/**
	 * @inheritDoc
	 */
	public function validate() {
		parent::validate();
		
		// validate action
		if (empty($this->action)) {
			throw new UserInputException('action');
		}
		
		if (!isset($this->actions[$this->action])) {<commit_msg>Only execute bulk processing action if action affects any object<commit_after><?php
namespace wcf\acp\form;
use wcf\data\object\type\ObjectType;
use wcf\data\object\type\ObjectTypeCache;
use wcf\form\AbstractForm;
use wcf\system\exception\IllegalLinkException;
use wcf\system\exception\UserInputException;
use wcf\system\WCF;

/**
 * Abstract implementation of a form for bulk processing objects of a certain type.
 * 
 * @author	<NAME>
 * @copyright	2001-2017 WoltLab GmbH
 * @license	GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 * @package	WoltLabSuite\Core\Acp\Form
 * @since	3.0
 */
abstract class AbstractBulkProcessingForm extends AbstractForm {
	/**
	 * object action object type types
	 * @var	ObjectType[]
	 */
	public $actions = [];
	
	/**
	 * number of objects affected by bulk processing
	 * @var	integer
	 */
	public $affectedObjectCount = 0;
	
	/**
	 * object condition object type types
	 * @var	ObjectType[][]
	 */
	public $conditions = [];
	
	/**
	 * list with bulk processed objects
	 * @var	\wcf\data\DatabaseObjectList
	 */
	public $objectList = null;
	
	/**
	 * bulk processable object type
	 * @var	ObjectType
	 */
	public $objectType = null;
	
	/**
	 * name of the bulk processable object type
	 * @var	string
	 */
	public $objectTypeName = '';
	
	/**
	 * @inheritDoc
	 */
	public $templateName = 'bulkProcessing';
	
	/**
	 * @inheritDoc
	 */
	public function assignVariables() {
		parent::assignVariables();
		
		$classParts = explode('\\', get_class($this));
		
		WCF::getTPL()->assign([
			'actions' => $this->actions,
			'affectedObjectCount' => $this->affectedObjectCount,
			'controller' => str_replace('Form', '', array_pop($classParts)),
			'controllerApplication' => $classParts[0],
			'conditions' => $this->conditions,
			'objectType' => $this->objectType
		]);
	}
	
	/**
	 * @inheritDoc
	 */
	public function readData() {
		// read bulk processable object type
		$this->objectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.bulkProcessableObject', $this->objectTypeName);
		if ($this->objectType === null) {
			throw new \LogicException("Unknown bulk processable object type '".$this->objectTypeName."'");
		}
		
		// read conditions
		if (ObjectTypeCache::getInstance()->getDefinitionByName($this->objectType->getProcessor()->getConditionObjectTypeDefinition()) === null) {
			throw new \LogicException("Unknown condition object type definition '".$this->objectType->getProcessor()->getConditionObjectTypeDefinition()."'");
		}
		$conditionObjectTypes = ObjectTypeCache::getInstance()->getObjectTypes($this->objectType->getProcessor()->getConditionObjectTypeDefinition());
		if (empty($conditionObjectTypes)) {
			throw new IllegalLinkException();
		}
		
		foreach ($conditionObjectTypes as $objectType) {
			if ($objectType->conditiongroup) {
				if (!isset($this->conditions[$objectType->conditiongroup])) {
					$this->conditions[$objectType->conditiongroup] = [];
				}
				
				$this->conditions[$objectType->conditiongroup][$objectType->objectTypeID] = $objectType;
			}
			else {
				$this->conditions[''][$objectType->objectTypeID] = $objectType;
			}
		}
		
		// read actions
		if (ObjectTypeCache::getInstance()->getDefinitionByName($this->objectType->getProcessor()->getActionObjectTypeDefinition()) === null) {
			throw new \LogicException("Unknown action object type definition '".$this->objectType->getProcessor()->getActionObjectTypeDefinition()."'");
		}
		
		$actions = ObjectTypeCache::getInstance()->getObjectTypes($this->objectType->getProcessor()->getActionObjectTypeDefinition());
		foreach ($actions as $objectType) {
			if (isset($this->actions[$objectType->action])) {
				throw new \LogicException("Duplicate action with name '".$objectType->action."'");
			}
			
			if ($objectType->validateOptions() && $objectType->validatePermissions()) {
				$this->actions[$objectType->action] = $objectType;
			}
		}
		if (empty($this->actions)) {
			throw new IllegalLinkException();
		}
		
		parent::readData();
	}
	
	/**
	 * @inheritDoc
	 */
	public function readFormParameters() {
		parent::readFormParameters();
		
		foreach ($this->conditions as $groupedObjectTypes) {
			foreach ($groupedObjectTypes as $objectType) {
				$objectType->getProcessor()->readFormParameters();
			}
		}
		
		if (isset($this->actions[$this->action])) {
			$this->actions[$this->action]->getProcessor()->readFormParameters();
		}
	}
	
	/**
	 * @inheritDoc
	 */
	public function save() {
		$this->objectList = $this->actions[$this->action]->getProcessor()->getObjectList();
		
		parent::save();
		
		// read objects
		foreach ($this->conditions as $groupedObjectTypes) {
			foreach ($groupedObjectTypes as $objectType) {
				$data = $objectType->getProcessor()->getData();
				if ($data !== null) {
					$objectType->getProcessor()->addObjectListCondition($this->objectList, $data);
				}
			}
		}
		$this->objectList->readObjects();
		
		// execute action
		if (count($this->objectList)) {
			$this->actions[$this->action]->getProcessor()->executeAction($this->objectList);
		}
		
		$this->affectedObjectCount = count($this->objectList);
		
		$this->saved();
		
		// reset fields
		$this->actions[$this->action]->getProcessor()->reset();
		
		foreach ($this->conditions as $groupedObjectTypes) {
			foreach ($groupedObjectTypes as $objectType) {
				$objectType->getProcessor()->reset();
			}
		}
		$this->action = '';
		
		WCF::getTPL()->assign('success', true);
	}
	
	/**
	 * @inheritDoc
	 */
	public function validate() {
		parent::validate();
		
		// validate action
		if (empty($this->action)) {
			throw new UserInputException('action');
		}
		
		if (!isset($this->actions[$this->action])) {
{'fraction_non_alphanumeric': 0.16628359264497877, 'fraction_numerical': 0.0021216407355021216, 'mean_word_length': 4.266759776536313, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 204, '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': '2406452', 'n_tokens_mistral': 3792, 'n_tokens_neox': 3234, 'n_words': 629}