Prune orphan attachments.

@return self
555624
protected function pruneAttachments()
    {
        $cli   = $this->climate();
        $ask   = $this->interactive();
        $dry   = $this->dryRun();
        $verb  = $this->verbose();
        $mucho = ($dry || $verb);

        $attach = $this->modelFactory()->get(Attachment::class);
        $pivot  = $this->modelFactory()->get(Join::class);
        $loader = $this->collection(Attachment::class);

        $sql = 'SELECT a.* FROM `%attachTable` AS a
                LEFT JOIN `%pivotTable` AS p
                ON a.id = p.attachment_id
                WHERE p.attachment_id IS NULL;';
        $binds = [
            '%attachTable' => $attach->source()->table(),
            '%pivotTable'  => $pivot->source()->table(),
        ];

        $collection = $loader->loadFromQuery(strtr($sql, $binds));

        $this->total = count($collection);
        if (!$this->describeCount(
            $this->total,
            '%d unused attachments were found.',
            '%d unused attachment was found.',
            'All attachments are associated!'
        )) {
            return $this;
        }

        $prompt = $this->promptToStart();
        if ($prompt === 'view') {
            $this->setVerbose(true);
            $this->setQuiet(false);
            $mucho = true;
            $dry = true;
            $ask = false;
        } elseif ($prompt === false) {
            $cli->br()->info('Canceled Cleanup');
            return $this;
        }

        if ($ask) {
            $cli->br();
        }

        $data   = [];
        $length = strlen(strval($this->total));

        $this->remainder = $this->total;
        $this->indent    = str_repeat(' ', (($length * 2) + 4));

        $prop = $attach->property($attach->key());
        if ($prop && preg_match('~\b\w+\((?<length>\d+)\)~', $prop->sqlType(), $matches)) {
            $pad = (intval($matches['length']) + 5);
        } else {
            $pad = 20;
        }

        foreach ($collection as $obj) {
            $this->remainder--;
            $this->processed++;

            $title = strval($obj->title());
            $objId = $obj->id();

            if ($mucho) {
                $dead = [
                    'Title'       => $title,
                    'Created on'  => $obj->created()->format('Y-m-d H:i:s'),
                    'Created by'  => $obj->createdBy(),
                    'Modified on' => $obj->lastModified()->format('Y-m-d H:i:s'),
                    'Modified by' => $obj->lastModifiedBy(),
                    'Type'        => $obj->type(),
                ];

                if ($ask && $verb) {
                    $dead = array_merge([ 'Deleted' => null, 'Failed' => null ], $dead);
                }
            }

            if ($ask) {
                $type  = sprintf('[%s]', $obj->microType());
                $label = sprintf('#%1$s %2$s', str_pad($objId, $pad), str_pad($type, 20));
                if ($title) {
                    $label = sprintf('%1$s "%2$s"', $label, $title);
                }

                $cli->out(
                    sprintf(
                        '%'.$length.'d/%-'.$length.'s — <yellow>%s</yellow>',
                        $this->processed,
                        $this->total,
                        $label
                    )
                );
            }

            if ($dry) {
                $this->pruned++;

                if ($mucho) {
                    $data[$objId] = $dead;
                }
            } elseif ($ask) {
                if ($this->action === null || $this->repeat === 0) {
                    $this->promptForDeletion();
                }

                if ($this->action === 'y') {
                    $this->deleteObject($obj, $this->pruned, $this->failed, $dead);
                } else {
                    $this->ignored++;
                }

                if ($this->repeat > 0) {
                    $this->repeat--;
                }

                if ($mucho) {
                    $data[$objId] = $dead;
                }

                continue;
            }
        }

        if ($ask) {
            $input = $cli->confirm('Reset auto-incremented IDs?');
            $cli->br();
            if ($input->confirmed()) {
                $sql = 'SET @num := 0;
                        UPDATE `%pivotTable` SET id = @num := (@num + 1);
                        ALTER TABLE `%pivotTable` AUTO_INCREMENT = 1;';
                $attach->source()->db()->query(strtr($sql, $binds));
            }
        }

        if ($mucho && $data) {
            $input = $cli->confirm('View details of cleanup?');
            if (!$ask) {
                $cli->br()->table($data);
            } else {
                $cli->br();
                if ($input->confirmed()) {
                    $cli->br()->table($data);
                }
            }
        }

        $cli->br();

        if ($dry) {
            if ($this->pruned) {
                $this->messages[] = sprintf(
                    '<yellow>%d attachment%s can be removed.</yellow>',
                    $this->pruned,
                    ($this->pruned > 1 ? 's' : '')
                );
            }
        } else {
            if ($this->pruned) {
                $this->messages[] = sprintf(
                    '<green>%d attachment%s successfully removed.</green>',
                    $this->pruned,
                    ($this->pruned > 1 ? 's were' : ' was')
                );
            }

            if ($this->failed) {
                $this->messages[] = sprintf(
                    '<light_red>%d attachment%s could not be removed.</light_red>',
                    $this->failed,
                    ($this->failed > 1 ? 's' : '')
                );
            }

            if ($this->ignored) {
                $this->messages[] = sprintf(
                    '%d unused attachment%s were ignored.',
                    $this->ignored,
                    ($this->ignored > 1 ? 's' : '')
                );
            }
        }

        $this->conclude();

        return $this;
    }
1228166
public function clear()
    {
        $this->mailer = null;
        $this->to = $this->attachemnts = array();
        $this->subject = $this->message = false;
        return $this;
    }
1349270
public function clear() {
        $children = $this->children();
        foreach ($children as $file) {
            $file->delete();
        }
        return $this;
    }
588466
public function removeFirst(): self
    {
        $tmpArray = $this->getArray();

        \array_shift($tmpArray);

        return static::create(
            $tmpArray,
            $this->iteratorClass,
            false
        );
    }
499555
public function detach()
    {
        $this->calendar->getEvents()->removeEvent($this);
        $this->calendar = null;

        return $this;
    }
1278066
public function pruneTerminatingProcesses()
    {
        $this->stopTerminatingProcessesThatAreHanging();

        $this->terminatingProcesses = collect(
            $this->terminatingProcesses
        )->filter(function ($process) {
            return $process['process']->isRunning();
        })->all();
    }
1124376
public function afterDelete()
    {
        Yii::$app->queue->push(new AttachmentDeleteJob([
            'path' => $this->path
        ]));
        return parent::afterDelete();
    }
1139794
public function removeLast(): self
    {
        $tmpArray = $this->getArray();

        \array_pop($tmpArray);

        return static::create(
            $tmpArray,
            $this->iteratorClass,
            false
        );
    }
259119
public function actionClear()
    {
        $query = AttachmentFile::find()->temporary();

        foreach ($query->batch(10) as $models) {
            /** @var AttachmentFile $model */
            foreach ($models as $model) {
                $url = $model->filePath;

                if ($model->delete()) {
                    $this->stdout('File ');
                    $this->stdout($url, Console::FG_YELLOW);
                    $this->stdout(' deleted');
                    echo PHP_EOL;
                }
            }
        }
    }
397936
public function discard()
    {
        $args = func_get_args();
        $this->discards = array_merge($this->discards, $this->args_to_array($args));

        return $this;
    }
1006998
public function onlyTrashed()
	{
		$this->withTrashed();

		$this->query->whereNotNull($this->model->getQualifiedDeletedAtColumn());

		return $this;
	}
93123
public function clear() {
		$this->_value = null;
		$this->getConnection()->getClient()->delete($this->name);
		return $this;
	}
543039
public function delete() {

		if(false !== $this -> file -> getExists()) {

			if(unlink($this -> file -> getBasepath())) {
				$this -> refresh();
			}
		}

		return $this;
	}
242835
public function prune() {
		if ( ! $this->enabled ) {
			return false;
		}

		/** @var Finder $finder */
		$finder = $this->get_finder()->sortByName();

		$files_to_delete = array();

		foreach ( $finder as $file ) {
			$pieces    = explode( '-', $file->getBasename( $file->getExtension() ) );
			$timestamp = end( $pieces );

			// No way to compare versions, do nothing.
			if ( ! is_numeric( $timestamp ) ) {
				continue;
			}

			$basename_without_timestamp = str_replace( '-' . $timestamp, '', $file->getBasename() );

			// There's a file with an older timestamp, delete it.
			if ( isset( $files_to_delete[ $basename_without_timestamp ] ) ) {
				unlink( $files_to_delete[ $basename_without_timestamp ] );
			}

			$files_to_delete[ $basename_without_timestamp ] = $file->getRealPath();
		}

		return true;
	}
846199
public function remove()
    {
        unset($this->_nodes[$this->_pointer]);
        $this->_nodes = array_values($this->_nodes);
        return $this;
    }
234575
public function strip()
    {
        $this->noAccent()
            ->trim()
            ->toLower()
            ->replace(array_keys(static::$charStrip), array_values(static::$charStrip))
            ->pregReplace(array('#[^a-z0-9-]#S', '#-+#S'), array('', '-'));

        return $this;
    }
142603
public function clean()
    {
        foreach ($this->data as $key => $data) {
            if (empty($data)) {
                unset($this->data[$key]);
            }
        }

        return $this;
    }