I want to make sure that when adding a post to the site, the name is formed from a random word or phrase (from my dictionary - a set of words) and tags. Now I have made the name of the post to be created from categories and tags, but so often the names of the post are duplicated.
<?php
namespace Submitters;
use App;
use User;
use Lang;
class Submitter {
use \Purify;
use \Prepare;
use \Stats;
protected $app;
protected $sql;
protected $raw;
protected $type;
protected $post;
protected $user;
protected $notes;
protected $output;
public function __construct(App $app, $type)
{
$this->app = $app;
$this->sql = $app->make('db');
$this->user = $app->make('user');
$this->http = $app->make('http');
$this->note = $app->make('notes');
$this->config = $app->make('config');
$this->web = $app->make('webdata');
$this->submissionDisabled();
User::can('submit.content') ?: App::Redirect();
$this->type = $this->postType($type);
$this->output = $this->prepareData();
App::createTempdirDir();
$this->execute();
}
private function submissionDisabled() {
$can = $this->config->get('disable_submission') && ! User::isAdmin();
$can && die( Lang::get('submission_disabled') );
}
protected function countTags($tags) {
$tagsArray = array_map('trim', explode(',',$tags));
if ($this->config->get('tags_limit') && (sizeof($tagsArray) > $this->config->get('tags_limit')) ) {
die(Lang::get('maxtags_error'));
}
}
protected function addTags($tags) {
$tagsArray = array_map('trim', explode(',',$tags));
foreach ($tagsArray as $tag) { if (empty($tag)) continue;
if (!$this->sql->countRows('tags', 'keyword=?', $tag)) {
$this->sql->insert('tags', ['keyword' => $tag]);
}
}
}
private function isDraft() {
return $this->post('saveas') === "draft";
}
private function prepareData() {
$username = $this->user->get('username', $this->post('nick'));
$input = filter_input_array(INPUT_POST, [
'title' => [
'filter' => FILTER_SANITIZE_STRING,
'flags' => FILTER_FLAG_STRIP_LOW
],
'category' => [
'filter' => FILTER_SANITIZE_STRING,
'default' => ''
],
'tags' => [
'filter' => FILTER_CALLBACK,
'options' => function($json) {
return $this->prepareTags($json);
}
],
'desc' => [
'filter' => FILTER_CALLBACK,
'default' => '',
'options' => function($desc) {
return $this->purifyDescription($desc);
}
]
]);
return (object) array_merge($input, [
'time' => time(),
'type' => $this->type,
'logged' => $this->user->logged,
'status' => $this->getUserStatus(),
'user' => $this->isValid('user', $username),
'title' => $this->isValid('title', $input['category']. ' ' .$input['tags'])
//'title' => $this->isValid('title', $input['title'])
]);
}
private function getUserStatus() {
if ($this->isDraft()) { return -1; }
/* -------------------------------------------
-2 - Hidden // Visibility: invisible
-1 - Draft // Visibility: invisible
0 - Moderation // Visibility: invisible
1 - Moderation // Visibility: profiles
2 - Published // Visibility: everywhere
*/
$conf = $this->config->find('in_profile,autoaccept');
if ($this->user->logged) {
if ($this->user->isadmin || $conf->autoaccept) { return 2; }
if ($conf->in_profile) { return 1; }
}
return 0;
}
private function isValid($field, $value) {
$i = 0; $error = 0;
$ruleset = $this->getRules( $field );
if ($ruleset) {
foreach ( $ruleset as $rule => $cond ) {
switch ($rule) {
case 'not_empty': if (empty($value)) { $error++; } break;
case 'regex_test': if (!preg_match($cond[0], $value)) { $error++; } break;
case 'min_length': if (strlen($value) < $cond[0]) { $error++; } break;
case 'max_length': if (strlen($value) > $cond[0]) { $error++; } break;
case 'callback':
$fieldnc = (gettype($cond) === 'array') ? $cond[0] : $cond;
if (call_user_func($fieldnc, $value)) { $error++; } break;
}
if ($error) {
$info = $cond[1];
die($this->Error($info) ?: $info);
}
$i++;
} // END loop
} // if $ruleset
if (! $error) return $value;
}
private function getRules($field) {
$rules = [
'user' => [
'not_empty' => [ true, Lang::get('empty_username') ],
'min_length' => [ $this->config->get('user_minlen') , Lang::get('user_minlen') ],
'max_length' => [ $this->config->get('user_maxlen') , Lang::get('user_maxlen') ],
'regex_test' => [ '/^[0-9A-Za-z_-]+$/i' , Lang::get('login_invalid') ],
'callback' => function($value) {
if (! $this->user->logged && User::userExists($value) ) {
$this->Error('username_taken');
}
}
],
'title' => [
'not_empty' => [ true, Lang::get('empty_title') ],
'min_length' => [ $this->config->get('title_minlen') , Lang::get('title_minlen') ],
'max_length' => [ $this->config->get('title_maxlen') , Lang::get('title_maxlen') ]
]
];
return isset($rules[ $field ]) ? $rules[ $field ] : false;
}
protected function mkSaveDir($dir) {
if (!is_dir($dir)) {
$oldmask = umask(0);
mkdir($dir, 0777, true);
umask($oldmask);
}
}
protected function makeFolder($postID) {
$date = DATE . '/' . $postID;
$path = SAVE_DIR . '/' . $postID;
$save = PATH_SAVE .'/'. $postID;
$this->mkSaveDir($save);
return (object) ['save' => $save, 'date' => $date, 'path' => $path];
}
protected function moveFiles($destination) {
foreach (glob(PATH_TEMP.'/*') as $file) {
rename($file, $destination .'/'. basename($file));
} return glob( $destination .'/*' );
}
protected function clearFolder() {
if ( is_dir(PATH_TEMP) ) {
$files = glob(PATH_TEMP . '/*');
foreach( $files as $file ) {
if ( is_file($file) ) { unlink($file); }
} @rmdir(PATH_TEMP);
}
}
private function postType($type) {
$types = ['article', 'gif', 'gifimg','photos', 'video','audio','embed'];
return in_array($type, $types) ? $type : exit;
}
protected function Error($e) {
$error = [
'no_images' => Lang::get('art_add_photo'),
'submit_error' => Lang::get('post_submit_error'),
'title_invalid' => Lang::get('title_invalid_chars'),
'img_invalid_url' => Lang::get('img_invalid_url'),
'title_min_length' => Lang::get('title_minlen'),
'login_used' => Lang::get('username_taken'),
'login_invalid' => Lang::get('login_invalid'),
'user_min_len' => Lang::get('user_minlen'),
'user_max_len' => Lang::get('user_maxlen'),
'desc_length' => Lang::get('art_too_short'),
];
if (isset($error[$e])) { die($error[$e]); }
return false;
}
} // END Class
I made the name of the post to be created from categories and tags, but so often the names of the post are duplicated.
'title' => $this->isValid('title', $input['category']. ' ' .$input['tags'])
Answers
To generate a unique name for each post, you can consider combining the category, tags, and a random word or phrase from your dictionary. Here's how you can modify your code to include a random word or phrase:
use Illuminate\Support\Str; // Assuming you're using Laravel or have access to Laravel's Str class for string manipulation
// Inside the prepareData() method
$title = $input['category'] . ' ' . $input['tags'];
// Get a random word or phrase from your dictionary
$randomWord = $this->getRandomWordFromDictionary(); // Implement this method to fetch a random word or phrase
// Concatenate the random word/phrase with the title
$title .= ' ' . $randomWord;
// Validate and return the title
'title' => $this->isValid('title', $title)
You need to implement the getRandomWordFromDictionary()
method to fetch a random word or phrase from your dictionary. Here's a simple implementation assuming you have an array of words/phrases:
private function getRandomWordFromDictionary() {
$dictionary = ['word1', 'word2', 'phrase1', 'phrase2']; // Your array of words or phrases
return $dictionary[array_rand($dictionary)]; // Pick a random word or phrase
}
With this modification, each post's title will include the category, tags, and a random word or phrase, making it less likely for titles to be duplicated.