3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
6 * Generates fake data as example
10 * Copyright © 2017-2018 The Galette Team
12 * This file is part of Galette (http://galette.tuxfamily.org).
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2017-2018 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.9
37 namespace Galette\Util
;
41 use Galette\Core\I18n
;
42 use Galette\Core\Preferences
;
43 use Galette\Core\History
;
44 use Galette\Core\Login
;
45 use Galette\Entity\Adherent
;
46 use Galette\Entity\Contribution
;
47 use Galette\Repository\Titles
;
48 use Galette\Entity\Status
;
49 use Galette\Entity\ContributionsTypes
;
50 use Galette\Entity\Group
;
51 use Galette\Entity\Transaction
;
52 use Galette\Entity\PaymentType
;
55 * Generate random data
60 * @author Johan Cwiklinski <johan@x-tnd.be>
61 * @copyright 2017 The Galette Team
62 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
63 * @link http://galette.tuxfamily.org
64 * @see https://github.com/fzaninotto/Faker
65 * @since Available since 0.9dev - 2017-02-20
69 const DEFAULT_NB_MEMBERS
= 20;
70 const DEFAULT_NB_CONTRIB
= 5;
71 const DEFAULT_NB_GROUPS
= 5;
72 const DEFAULT_NB_TRANSACTIONS
= 2;
73 const DEFAULT_PHOTOS
= false;
75 protected $preferences;
76 protected $member_fields;
89 protected $groups = [];
91 protected $transactions = [];
92 protected $titles = [];
94 protected $contrib_types;
98 * Number of members to generate
100 protected $nbmembers = self
::DEFAULT_NB_MEMBERS
;
104 * With members photos
106 protected $with_photos = self
::DEFAULT_PHOTOS
;
110 * Number of groups to generate
112 protected $nbgroups = self
::DEFAULT_NB_GROUPS
;
116 * Max number of contributions to generate
119 protected $maxcontribs = self
::DEFAULT_NB_CONTRIB
;
123 * Number of transactions to generate
125 protected $nbtransactions = self
::DEFAULT_NB_TRANSACTIONS
;
129 * Seed to use for data generation (to get same data accross runs)
134 * Default constructor
136 * @param Db $zdb Db instance
137 * @param I18n $i18n Current language
138 * @param boolean $generate Process data generation; defaults to false
142 public function __construct(Db
$zdb, I18n
$i18n, $generate = false)
154 * @param integer $seed Seed
158 public function setSeed($seed)
165 * Set number of members to generate
167 * @param integer $nb Number of members
171 public function setNbMembers($nb)
173 $this->nbmembers
= (int)$nb;
178 * Set maximum number of contribution per member to generate
180 * @param integer $nb Number of contributions
184 public function setMaxContribs($nb)
186 $this->maxcontribs
= (int)$nb;
191 * Set number of groups to generate
193 * @param integer $nb Number of groups
197 public function setNbGroups($nb)
199 $this->nbgroups
= (int)$nb;
204 * Set number of transactions to generate
206 * @param integer $nb Number of transactions
210 public function setNbTransactions($nb)
212 $this->nbtransactions
= (int)$nb;
217 * Set with members photos or not
219 * @param boolean $with With photos
223 public function setWithPhotos($with)
225 $this->with_photos
= $with;
230 * Get (and create if needed) Faker instance
232 * @return \Faker\Factory
234 private function getFaker()
236 if ($this->faker
=== null) {
237 $this->faker
= \Faker\Factory
::create($this->i18n
->getID());
247 public function generate()
250 if ($this->seed
!== null) {
251 $this->faker
->seed($this->seed
);
254 $this->generateGroups($this->nbgroups
);
255 $this->generateMembers($this->nbmembers
);
256 $this->generateTransactions($this->nbtransactions
);
257 $this->generateContributions();
263 * @param integer $count Number of groups to generate
267 public function generateGroups($count = null)
269 $faker = $this->getFaker();
272 $parent_group = null;
274 if ($count === null) {
275 $count = $this->nbgroups
;
278 for ($i = 0; $i < $count; $i++
) {
279 $group = new Group();
280 $group->setName($faker->unique()->lastName());
281 if (count($this->groups
) > 0 && $faker->boolean($chanceOfGettingTrue = 10)) {
282 if ($parent_group === null) {
283 $parent_group = $faker->randomElement($this->groups
);
285 $group->setParentGroup($parent_group->getId());
288 if ($group->store()) {
289 $this->groups
[] = $group;
294 if ($count !=0 && $done != 0) {
295 if ($done === $count) {
297 str_replace('%count', $count, _T("%count groups created"))
304 _T("%count groups requested, and %done created")
314 * @param integer $count Number of members to generate
318 public function generateMembers($count = null)
320 $faker = $this->getFaker();
324 if ($count === null) {
325 $count = $this->nbmembers
;
328 for ($i = 0; $i < $count; $i++
) {
329 $data = $this->fakeMember();
331 $member = new Adherent($this->zdb
);
332 $member->setDependencies(
334 $this->member_fields
,
337 if ($member->check($data, [], [])) {
338 if ($member->store()) {
339 $this->mids
[] = $member->id
;
341 if ($this->with_photos
&& $faker->boolean($chanceOfGettingTrue = 70)) {
342 if ($this->addPhoto($member)) {
349 if (count($this->groups
) > 0 && $faker->boolean($chanceOfGettingTrue = 60)) {
350 $groups = $faker->randomElements($this->groups
);
351 foreach ($groups as $group) {
352 $manager = $faker->boolean($chanceOfGettingTrue = 10);
354 $managers = $group->getManagers();
355 $managers[] = $member;
356 $group->setManagers($managers);
358 $members = $group->getMembers();
359 $members[] = $member;
360 $group->setMembers($members);
367 if ($count !=0 && $done != 0) {
368 if ($done === $count) {
370 str_replace('%count', $count, _T("%count members created"))
377 _T("%count members requested, and %done created")
382 if ($this->with_photos
=== true) {
383 if ($photos_done > 0) {
385 str_replace('%count', $count, _T("%count photos created"))
389 _T("No photo has been created")
396 * Get faked member data
400 public function fakeMember()
402 $faker = $this->getFaker();
403 if ($this->seed
!== null) {
404 $this->faker
->seed($this->seed
);
406 $creation_date = $faker->dateTimeBetween($startDate = '-3 years', $endDate = 'now');
407 $mdp_adh = $faker->password();
409 if ($this->status
=== null) {
410 $status = new Status($this->zdb
);
411 $this->status
= array_keys($status->getList());
415 'nom_adh' => $faker->lastName(),
416 'prenom_adh' => $faker->firstName(),
417 'ville_adh' => $faker->city(),
418 'cp_adh' => $faker->postcode(),
419 'adresse_adh' => $faker->streetAddress(),
420 'ville_adh' => $faker->city(),
421 'email_adh' => $faker->unique()->email(),
422 'login_adh' => $faker->unique()->userName(),
423 'mdp_adh' => $mdp_adh,
424 'mdp_adh2' => $mdp_adh,
425 'bool_admin_adh' => $faker->boolean($chanceOfGettingTrue = 5),
426 'bool_exempt_adh' => $faker->boolean($chanceOfGettingTrue = 5),
427 'bool_display_info' => $faker->boolean($chanceOfGettingTrue = 70),
428 'sexe_adh' => $faker->randomElement([Adherent
::NC
, Adherent
::MAN
, Adherent
::WOMAN
]),
429 'prof_adh' => $faker->jobTitle(),
430 'titre_adh' => $faker->randomElement(array_keys($this->titles
)),
431 'ddn_adh' => $faker->dateTimeBetween(
432 $startDate = '-110 years',
433 $endDate = date('Y-m-d')
434 )->format(_T("Y-m-d")),
435 'lieu_naissance' => $faker->city(),
436 'pseudo_adh' => $faker->userName(),
437 'adresse_adh' => $faker->streetAddress(),
438 'cp_adh' => $faker->postcode(),
439 'ville_adh' => $faker->city(),
440 'pays_adh' => $faker->optional()->country(),
441 'tel_adh' => $faker->phoneNumber(),
442 'url_adh' => $faker->optional()->url(),
443 'activite_adh' => $faker->boolean($chanceOfGettingTrue = 90),
444 'id_statut' => $faker->optional($weight = 0.3, $default = Status
::DEFAULT_STATUS
)
445 ->randomElement($this->status
),
446 'date_crea_adh' => $creation_date->format(_T("Y-m-d")),
447 'pref_lang' => $faker->randomElement(array_keys($this->i18n
->getArrayList())),
448 'fingerprint' => 'FAKER' . ($this->seed
!== null ?
$this->seed
: '')
451 if ($faker->boolean($chanceOfGettingTrue = 20)) {
452 $data['societe_adh'] = $faker->company();
453 $data['is_company'] = true;
460 * Add photo to a member
462 * @param Adherent $member Member instance
466 public function addPhoto(Adherent
$member)
468 $file = GALETTE_TEMPIMAGES_PATH
. 'fakephoto.jpg';
469 if (!defined('GALETTE_TESTS')) {
470 $faker = $this->getFaker();
471 $url = $faker->unique()->imageUrl(
479 $url = GALETTE_ROOT
. '../tests/fake_image.jpg';
482 if (copy($url, $file)) {
485 'name' => 'fakephoto.jpg',
486 'type' => 'image/jpeg',
487 'size' => filesize($file),
492 $res = $member->picture
->store($_FILES['photo'], true);
495 _T("Photo has not been stored!")
502 _T("Photo has not been copied!")
509 * Generate transactions
511 * @param integer $count Number of transactions to generate
512 * @param array $mids Members ids. Defaults to null (will work with previously generated ids)
516 public function generateTransactions($count = null, $mids = null)
518 $faker = $this->getFaker();
522 if ($count === null) {
523 $count = $this->nbtransactions
;
526 if ($mids === null) {
530 for ($i = 0; $i < $count; $i++
) {
532 'trans_date' => $faker->dateTimeBetween($startDate = '-1 years', $endDate = 'now')->format(_T("Y-m-d")),
533 Adherent
::PK
=> $faker->randomElement($mids),
534 'trans_amount' => $faker->numberBetween($min = 50, $max = 2000),
535 'trans_desc' => $faker->realText($maxNbChars = 150)
538 $transaction = new Transaction($this->zdb
, $this->login
);
539 if ($transaction->check($data, [], [])) {
540 if ($transaction->store($this->history
)) {
541 $this->transactions
[] = $transaction;
547 if ($count !=0 && $done != 0) {
548 if ($done === $count) {
550 str_replace('%count', $count, _T("%count transactions created"))
557 _T("%count transactions requested, and %done created")
565 * Generate members contributions
567 * @param array $mids Members ids. Defaults to null (will work with previously generated ids)
571 public function generateContributions($mids = null)
573 $faker = $this->getFaker();
575 if ($this->maxcontribs
== 0) {
579 if ($mids === null) {
585 foreach ($mids as $mid) {
586 $nbcontribs = $faker->numberBetween(0, $this->maxcontribs
);
587 for ($i = 0; $i < $nbcontribs; $i++
) {
588 $data = $this->fakeContrib($mid);
589 $contrib = new Contribution($this->zdb
, $this->login
);
590 if ($contrib->check($data, [], []) === true) {
591 if ($contrib->store()) {
592 $pk = Contribution
::PK
;
593 $this->cids
[] = $contrib->$pk;
597 if (count($this->transactions
) > 0) {
598 if ($faker->boolean($chanceOfGettingTrue = 90)) {
599 $contrib::setTransactionPart(
612 str_replace('%count', $done, _T("%count contributions created"))
616 _T("No contribution created!")
622 * Get faked contribution data
624 * @param integer $mid Member id.
628 public function fakeContrib($mid)
630 $faker = $this->getFaker();
631 if ($this->seed
!== null) {
632 $this->faker
->seed($this->seed
);
635 if ($this->contrib_types
=== null) {
636 $ct = new ContributionsTypes($this->zdb
);
637 $this->contrib_types
= $ct->getCompleteList();
639 $types = $this->contrib_types
;
641 $begin_date = $faker->dateTimeBetween($startDate = '-3 years', $endDate = 'now');
642 $end_date = clone $begin_date;
643 $end_date->modify('+1 year');
645 $begin_date = new \
DateTime();
649 Adherent
::PK
=> $mid,
650 ContributionsTypes
::PK
=> $faker->randomElement(array_keys($types)),
651 'montant_cotis' => $faker->numberBetween($min = 5, $max = 200),
652 'type_paiement_cotis' => $faker->randomElement(
656 PaymentType
::CREDITCARD
,
658 PaymentType
::TRANSFER
,
662 'info_cotis' => ($this->seed
!== null ?
663 'FAKER' . $this->seed
:
664 $faker->optional($weight = 0.1)->realText($maxNbChars = 500)),
665 'date_enreg' => $faker->dateTimeBetween($startDate = '-1 years', $endDate = 'now')->format(_T("Y-m-d")),
666 'date_debut_cotis' => $begin_date->format(_T("Y-m-d")),
667 'date_fin_cotis' => $end_date->format(_T("Y-m-d"))
670 if (count($this->transactions
) > 0) {
671 if ($faker->boolean($chanceOfGettingTrue = 90)) {
672 $transaction = $faker->randomElement($this->transactions
);
673 $missing = $transaction->getMissingAmount();
674 if ($data['montant_cotis'] > $missing) {
675 $data['montant_cotis'] = $missing;
684 * Add success message
686 * @param string $msg Message
690 protected function addSuccess($msg)
692 $this->report
['success'][] = $msg;
698 * @param string $msg Message
702 protected function addError($msg)
704 $this->report
['errors'][] = $msg;
708 * Add warning message
710 * @param string $msg Message
714 protected function addWarning($msg)
716 $this->report
['warnings'][] = $msg;
724 public function getReport()
726 return $this->report
;
732 * @param Preferences $preferences Preferences instance
733 * @param array $fields Members fields configuration
734 * @param History $history History instance
735 * @param Login $login Login instance
739 public function setDependencies(
740 Preferences
$preferences,
745 $this->preferences
= $preferences;
746 $this->member_fields
= $fields;
747 $this->history
= $history;
748 $this->login
= $login;
754 * Get generated members ids
758 public function getMembersIds()