1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8namespace Tiki\Command; 9 10use DateInterval; 11use DateTimeInterface; 12use Exception; 13use Symfony\Component\Console\Command\Command; 14use Symfony\Component\Console\Input\InputArgument; 15use Symfony\Component\Console\Input\InputInterface; 16use Symfony\Component\Console\Input\InputOption; 17use Symfony\Component\Console\Output\OutputInterface; 18use Faker\Factory as FakerFactory; 19use TikiLib; 20use Tiki\Faker as TikiFaker; 21 22/** 23 * Enabled the usage of Faker as a way to load random data to trackers 24 */ 25class FakerCommentsCommand extends Command 26{ 27 /** 28 * Configures the current command. 29 */ 30 protected function configure() 31 { 32 $this 33 ->setName('faker:comments') 34 ->setDescription('Generate comments fake data') 35 ->addArgument( 36 'object', 37 InputArgument::REQUIRED, 38 'Object Id' 39 ) 40 ->addArgument( 41 'type', 42 InputArgument::OPTIONAL, 43 'Object Type', 44 'wiki page' 45 ) 46 ->addOption( 47 'items', 48 'i', 49 InputOption::VALUE_OPTIONAL, 50 'Number of comments (items) to generate', 51 100 52 ) 53 ->addOption( 54 'replies', 55 'r', 56 InputOption::VALUE_OPTIONAL, 57 'Percentage of comments as replies', 58 40 59 ) 60 ->addOption( 61 'anonymous', 62 'a', 63 InputOption::VALUE_OPTIONAL, 64 'Percentage of anonymous posts if permitted', 65 20 66 ) 67 ->addOption( 68 'minstart', 69 's', 70 InputOption::VALUE_OPTIONAL, 71 'Earliest start date for first comment', 72 '-1 year' 73 ) 74 ->addOption( 75 'maxstart', 76 'e', 77 InputOption::VALUE_OPTIONAL, 78 'Latest start date for first comment', 79 '-11 months' 80 ) 81 ->addOption( 82 'mingap', 83 '', 84 InputOption::VALUE_OPTIONAL, 85 'Shortest gap between comments', 86 '10 minutes' 87 ) 88 ->addOption( 89 'maxgap', 90 'g', 91 InputOption::VALUE_OPTIONAL, 92 'Longest gap between comments', 93 '5 days' 94 ); 95 } 96 97 /** 98 * Executes the current command. 99 * 100 * @param InputInterface $input 101 * @param OutputInterface $output 102 * 103 * @return null|int 104 * @throws Exception 105 */ 106 protected function execute(InputInterface $input, OutputInterface $output) 107 { 108 global $prefs; 109 110 $commentslib = TikiLib::lib('comments'); 111 $tikilib = TikiLib::lib('tiki'); 112 113 if (! class_exists('\Faker\Factory')) { 114 $output->writeln('<error>' . tra('Please install Faker package') . '</error>'); 115 return null; 116 } 117 118 $objectId = $input->getArgument('object'); 119 $objectType = $input->getArgument('type'); 120 121 // check for object's existence 122 if (! TikiLib::lib('object')->get_object_id($objectType, $objectId)) { 123 $output->writeln('<error>' . tr('Object "%0" of type "%1" not found', $objectId, $objectType) . '</error>'); 124 return null; 125 } 126 127 $numberItems = $input->getOption('items'); 128 if (! is_numeric($numberItems)) { 129 $output->writeln('<error>' . tra('The value of items is not a number') . '</error>'); 130 return null; 131 } 132 133 $numberItems = (int)$numberItems; 134 135 $replyPercentage = $input->getOption('replies'); 136 $anonymousPercentage = $input->getOption('anonymous'); 137 138 // dates 139 $minStart = $input->getOption('minstart'); 140 $maxStart = $input->getOption('maxstart'); 141 $minGap = $input->getOption('mingap'); 142 $maxGap = $input->getOption('maxgap'); 143 144 $faker = FakerFactory::create(); 145 $tikiFaker = new TikiFaker($faker); 146 $faker->addProvider($tikiFaker); 147 148 $startDate = $faker->dateTimeBetween($minStart, $maxStart); 149 $lastDateTime = $startDate; 150 $lastDateTime->add(DateInterval::createFromDateString($minGap)); 151 152 $fakerMap = [ 153 'title' => '', 154 'data' => 'text', 155 ]; 156 157 if ($prefs['comments_notitle'] !== 'y') { 158 $fakerMap['title'] = ['text', [30]]; 159 } 160 161 $threadId = 0; 162 // need user names, jnot real 163 $showRealNames = $prefs['user_show_realnames']; 164 $prefs['user_show_realnames'] = 'n'; 165 166 for ($i = 0; $i < $numberItems; $i++) { 167 168 if ($prefs['feature_comments_post_as_anonymous'] === 'y' && random_int(0, 100) < $anonymousPercentage) { 169 $fakerMap['userName'] = ''; 170 $fakerMap['anonymous_name'] = 'name'; 171 $fakerMap['anonymous_email'] = 'email'; 172 $fakerMap['website'] = 'url'; 173 } else { 174 $fakerMap['userName'] = ['tikiUserSelector', false,]; 175 $fakerMap['anonymous_name'] = ''; 176 $fakerMap['anonymous_email'] = ''; 177 $fakerMap['website'] = ''; 178 } 179 180 $commentData = []; 181 182 foreach ($fakerMap as $argument => $thisFaker) { 183 184 if (is_array($thisFaker)) { 185 $fakerAction = $thisFaker[0]; 186 $fakerArguments = $thisFaker[1]; 187 if (! is_array($fakerArguments)) { 188 $fakerArguments = [$fakerArguments]; 189 } 190 $value = call_user_func_array([$faker, $fakerAction], $fakerArguments); 191 } elseif (! empty($thisFaker)) { 192 $fakerAction = $thisFaker; 193 $value = $faker->$fakerAction; 194 } else { 195 $value = ''; 196 } 197 198 if (isset($value)) { 199 $commentData[$argument] = $value; 200 } 201 } 202 203 // special handling for commentDateTime 204 205 $commentDateTime = $faker->dateTimeInInterval($lastDateTime->format(DateTimeInterface::ATOM), $maxGap); 206 207 if (! empty($commentData)) { 208 $message_id = ''; // returned by reference 209 if ($threadId && random_int(0, 100) < $replyPercentage) { 210 $parentId = $threadId; // add thread parent here sometimes 211 } else { 212 $parentId = 0; 213 } 214 $commentDateUnix = $commentDateTime->format('U'); 215 if ($prefs['comments_notitle'] === 'y') { 216 $commentData['title'] = 'Untitled ' . $tikilib->get_long_datetime($commentDateUnix); 217 } 218 219 try { 220 $threadId = $commentslib->post_new_comment( 221 "$objectType:$objectId", 222 $parentId, 223 $commentData['userName'], 224 $commentData['title'], 225 $commentData['data'], 226 $message_id, 227 '', // reply to for forums only? 228 'n', 229 '', 230 '', 231 [], 232 $commentData['anonymous_name'], 233 $commentDateUnix, 234 $commentData['anonymous_email'], 235 $commentData['website'], 236 [], // parent info for forums 237 0 // version of object for save and comment 238 ); 239 } catch (Exception $e) { 240 $output->writeln('<error>' . $e->getMessage() . '</error>'); 241 } 242 243 $lastDateTime = $commentDateTime; 244 } 245 } 246 247 $prefs['user_show_realnames'] = $showRealNames; 248 249 return 0; 250 } 251 252 253} 254