"psr/container": "^1.0",
"php-di/slim-bridge": "2.0.0",
"doctrine/annotations": "^1.8",
- "laminas/laminas-servicemanager": "3.7"
+ "laminas/laminas-servicemanager": "3.7",
+ "symfony/polyfill-php80": "^1.23"
},
"require-dev": {
"atoum/atoum": "dev-master",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "58771c7f593b6023a54dbe5cd3fa9a99",
+ "content-hash": "abdb30cee5eeb0dad05c159a1c10880d",
"packages": [
{
"name": "akrabat/rka-slim-session-middleware",
},
"time": "2019-02-15T01:44:54+00:00"
},
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.23.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
+ "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-07-28T13:41:28+00:00"
+ },
{
"name": "tecnickcom/tcpdf",
"version": "6.4.2",
],
"time": "2021-02-19T12:13:01+00:00"
},
- {
- "name": "symfony/polyfill-php80",
- "version": "v1.23.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
- "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.23-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php80\\": ""
- },
- "files": [
- "bootstrap.php"
- ],
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ion Bazan",
- "email": "ion.bazan@gmail.com"
- },
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2021-07-28T13:41:28+00:00"
- },
{
"name": "symfony/service-contracts",
"version": "v2.4.0",
'position' => 18,
'category' => FieldsCategories::ADH_CATEGORY_CONTACT
),
- 'url_adh' => array(
- 'label' => _T("Website:"),
- 'propname' => 'website',
- 'required' => false,
- 'visible' => FieldsConfig::USER_WRITE,
- 'position' => 19,
- 'category' => FieldsCategories::ADH_CATEGORY_CONTACT
- ),
- 'icq_adh' => array(
- 'label' => _T("ICQ:"),
- 'propname' => 'icq',
- 'required' => false,
- 'visible' => FieldsConfig::NOBODY,
- 'position' => 20,
- 'category' => FieldsCategories::ADH_CATEGORY_CONTACT
- ),
- 'msn_adh' => array(
- 'label' => _T("MSN:"),
- 'propname' => 'msn',
- 'required' => false,
- 'visible' => FieldsConfig::NOBODY,
- 'position' => 22,
- 'category' => FieldsCategories::ADH_CATEGORY_CONTACT
- ),
- 'jabber_adh' => array(
- 'label' => _T("Jabber:"),
- 'propname' => 'jabber',
- 'required' => false,
- 'visible' => FieldsConfig::USER_WRITE,
- 'position' => 21,
- 'category' => FieldsCategories::ADH_CATEGORY_CONTACT
- ),
'info_adh' => array(
'label' => _T("Other information (admin):"),
'propname' => 'others_infos_admin',
}
define('GALETTE_COMPAT_VERSION', '0.9.5');
-define('GALETTE_DB_VERSION', '0.950');
+define('GALETTE_DB_VERSION', '0.960');
if (!defined('GALETTE_MODE')) {
define('GALETTE_MODE', \Galette\Core\Galette::MODE_PROD);
}
tel_adh varchar(50) default NULL,
gsm_adh varchar(50) default NULL,
email_adh varchar(255) default NULL,
- url_adh varchar(255) default NULL,
- icq_adh varchar(20) default NULL, -- TODO: remove
- msn_adh varchar(150) default NULL, -- TODO: remove
- jabber_adh varchar(150) default NULL,
info_adh text,
info_public_adh text,
prof_adh varchar(150) default NULL,
PRIMARY KEY (target, id)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
+-- table for social networks
+DROP TABLE IF EXISTS galette_socials;
+CREATE TABLE galette_socials (
+ id_social int(10) unsigned NOT NULL auto_increment,
+ id_adh int(10) unsigned NULL,
+ type varchar(250) NOT NULL,
+ url varchar(255) DEFAULT NULL,
+ PRIMARY KEY (id_social),
+ KEY (type),
+ FOREIGN KEY (id_adh) REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
+
-- table for database version
DROP TABLE IF EXISTS galette_database;
CREATE TABLE galette_database (
version DECIMAL(4,3) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-INSERT INTO galette_database(version) VALUES(0.95);
+INSERT INTO galette_database(version) VALUES(0.96);
SET FOREIGN_KEY_CHECKS=1;
MINVALUE 1
CACHE 1;
+-- sequence for socials
+DROP SEQUENCE IF EXISTS galette_socials_id_seq;
+CREATE SEQUENCE galette_socials_id_seq
+ START 1
+ INCREMENT 1
+ MAXVALUE 2147483647
+ MINVALUE 1
+ CACHE 1;
+
-- Schema
-- REMINDER: Create order IS important, dependencies first !!
DROP TABLE IF EXISTS galette_paymenttypes;
tel_adh character varying(50),
gsm_adh character varying(50),
email_adh character varying(255),
- url_adh character varying(255),
- icq_adh character varying(20), -- TODO: remove
- msn_adh character varying(150), -- TODO: remove
- jabber_adh character varying(150),
info_adh text,
info_public_adh text,
prof_adh character varying(150),
PRIMARY KEY (target, id)
);
+-- table for social networks
+DROP TABLE IF EXISTS galette_socials;
+CREATE TABLE galette_socials (
+ id_social integer DEFAULT nextval('galette_socials_id_seq'::text) NOT NULL,
+ id_adh integer REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE,
+ type character varying(250) NOT NULL,
+ url character varying(255) DEFAULT NULL,
+ PRIMARY KEY (id_social)
+);
+-- add index on table to look for type
+CREATE INDEX galette_socials_idx ON galette_socials (type);
+
-- table for database version
DROP TABLE IF EXISTS galette_database;
CREATE TABLE galette_database (
version decimal NOT NULL
);
-INSERT INTO galette_database (version) VALUES(0.95);
+INSERT INTO galette_database (version) VALUES(0.96);
--- /dev/null
+CREATE TABLE galette_socials (
+ id_social int(10) unsigned NOT NULL auto_increment,
+ id_adh int(10) unsigned NULL,
+ type varchar(250) NOT NULL,
+ url varchar(255) DEFAULT NULL,
+ PRIMARY KEY (id_social),
+ KEY (type),
+ FOREIGN KEY (id_adh) REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
+
+-- migrate socials from preferences
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'google+', val_pref FROM galette_preferences WHERE nom_pref = 'pref_googleplus' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'facebook', val_pref FROM galette_preferences WHERE nom_pref = 'pref_facebook' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'twitter', val_pref FROM galette_preferences WHERE nom_pref = 'pref_twitter' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'linkedin', val_pref FROM galette_preferences WHERE nom_pref = 'pref_linkedin' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'viadeo', val_pref FROM galette_preferences WHERE nom_pref = 'pref_viadeo' AND val_pref != '';
+-- cleanup preferences
+DELETE FROM galette_preferences WHERE
+ nom_pref = 'pref_googleplus'
+ OR nom_pref = 'pref_facebook'
+ OR nom_pref = 'pref_twitter'
+ OR nom_pref = 'pref_linkedin'
+ OR nom_pref = 'pref_viadeo';
+-- update pdf card address
+UPDATE galette_preferences SET val_pref = 0 WHERE nom_pref = 'pref_card_address' AND val_pref IN ('1', '2', '3', '4');
+
+-- migrate members socials
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'website', url_adh FROM galette_adherents WHERE url_adh != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'icq', icq_adh FROM galette_adherents WHERE icq_adh != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'msn', msn_adh FROM galette_adherents WHERE msn_adh != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'jabber', jabber_adh FROM galette_adherents WHERE jabber_adh != '';
+-- cleanup members table
+ALTER TABLE galette_adherents DROP column url_adh;
+ALTER TABLE galette_adherents DROP column icq_adh;
+ALTER TABLE galette_adherents DROP column msn_adh;
+ALTER TABLE galette_adherents DROP column jabber_adh;
+-- cleanup fields config
+DELETE FROM galette_fields_config WHERE field_id IN ('url_adh', 'icq_adh', 'msn_adh', 'jabber_adh');
+
+UPDATE galette_database SET version = 0.960;
\ No newline at end of file
--- /dev/null
+-- sequence for socials
+CREATE SEQUENCE galette_socials_id_seq
+ START 1
+ INCREMENT 1
+ MAXVALUE 2147483647
+ MINVALUE 1
+ CACHE 1;
+
+CREATE TABLE galette_socials (
+ id_social integer DEFAULT nextval('galette_socials_id_seq'::text) NOT NULL,
+ id_adh integer REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE,
+ type character varying(250) NOT NULL,
+ url character varying(255) DEFAULT NULL,
+ PRIMARY KEY (id_social)
+);
+-- add index on table to look for type
+CREATE INDEX galette_socials_idx ON galette_socials (type);
+
+-- migrate socials from preferences
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'google+', val_pref FROM galette_preferences WHERE nom_pref = 'pref_googleplus' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'facebook', val_pref FROM galette_preferences WHERE nom_pref = 'pref_facebook' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'twitter', val_pref FROM galette_preferences WHERE nom_pref = 'pref_twitter' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'linkedin', val_pref FROM galette_preferences WHERE nom_pref = 'pref_linkedin' AND val_pref != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT null, 'viadeo', val_pref FROM galette_preferences WHERE nom_pref = 'pref_viadeo' AND val_pref != '';
+-- cleanup preferences
+DELETE FROM galette_preferences WHERE
+ nom_pref = 'pref_googleplus'
+ OR nom_pref = 'pref_facebook'
+ OR nom_pref = 'pref_twitter'
+ OR nom_pref = 'pref_linkedin'
+ OR nom_pref = 'pref_viadeo';
+-- update pdf card address
+UPDATE galette_preferences SET val_pref = 0 WHERE nom_pref = 'pref_card_address' AND val_pref IN ('1', '2', '3', '4');
+
+-- migrate members socials
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'website', url_adh FROM galette_adherents WHERE url_adh != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'icq', icq_adh FROM galette_adherents WHERE icq_adh != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'msn', msn_adh FROM galette_adherents WHERE msn_adh != '';
+INSERT INTO galette_socials (id_adh, type, url) SELECT id_adh, 'jabber', jabber_adh FROM galette_adherents WHERE jabber_adh != '';
+-- cleanup members table
+ALTER TABLE galette_adherents DROP column url_adh;
+ALTER TABLE galette_adherents DROP column icq_adh;
+ALTER TABLE galette_adherents DROP column msn_adh;
+ALTER TABLE galette_adherents DROP column jabber_adh;
+-- cleanup fields config table
+DELETE FROM galette_fields_config WHERE field_id IN ('url_adh', 'icq_adh', 'msn_adh', 'jabber_adh');
+
+UPDATE galette_database SET version = 0.960;
\ No newline at end of file
use Galette\Entity\Group;
use Galette\Entity\Status;
use Galette\Entity\FieldsConfig;
+use Galette\Entity\Social;
use Galette\Filters\AdvancedMembersList;
use Galette\Filters\MembersList;
use Galette\IO\File;
'member' => $member,
'self_adh' => true,
'autocomplete' => true,
+ 'osocials' => new Social($this->zdb),
// pseudo random int
'time' => time(),
'titles_list' => Titles::getList($this->zdb),
'pref_card_self' => $this->preferences->pref_card_self,
'groups' => Groups::getSimpleList(),
'time' => time(),
- 'display_elements' => $display_elements
+ 'display_elements' => $display_elements,
+ 'osocials' => new Social($this->zdb)
)
);
return $response;
$filters->setViewCommonsFilters($this->preferences, $this->view->getSmarty());
+ $social = new Social($this->zdb);
+ $types = $member->getMemberRegisteredTypes();
+ $social_types = [];
+ foreach ($types as $type) {
+ $social_types[$type] = $social->getSystemType($type);
+ }
+
// display page
$this->view->render(
$response,
'search_fields' => $fields,
'adh_dynamics' => $adh_dynamics->getFields(),
'contrib_dynamics' => $contrib_dynamics->getFields(),
+ 'adh_socials' => $social_types,
'statuts' => $statuts->getList(),
'contributions_types' => $ct->getList(),
'filters' => $filters,
'fieldsets' => $form_elements['fieldsets'],
'hidden_elements' => $form_elements['hiddens'],
'parent_fields' => $tpl_parent_fields,
- 'addchild' => ($action === 'addchild')
+ 'addchild' => ($action === 'addchild'),
+ 'osocials' => new Social($this->zdb)
) + $route_params
);
return $response;
namespace Galette\Controllers;
+use Galette\Entity\Social;
use Galette\Repository\PaymentTypes;
use Slim\Http\Request;
use Slim\Http\Response;
Members::ACTIVE_ACCOUNT => _T("Active accounts"),
Members::INACTIVE_ACCOUNT => _T("Inactive accounts")
),
- 'paymenttypes' => $ptlist
+ 'paymenttypes' => $ptlist,
+ 'osocials' => new Social($this->zdb)
)
);
return $response;
*
* PHP version 5
*
- * Copyright © 2009-2014 The Galette Team
+ * Copyright © 2009-2021 The Galette Team
*
* This file is part of Galette (http://galette.tuxfamily.org).
*
* @package Galette
*
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2009-2014 The Galette Team
+ * @copyright 2009-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since Available since 0.7dev - 2009-12-10
* @name GaletteMail
* @package Galette
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2009-2014 The Galette Team
+ * @copyright 2009-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since Available since 0.7dev - 2009-03-07
);
}
- if (trim($this->preferences->pref_mail_sign) != '') {
- $patterns = array(
- '/{NAME}/',
- '/{WEBSITE}/',
- '/{FACEBOOK}/',
- '/{GOOGLEPLUS}/',
- '/{TWITTER}/',
- '/{LINKEDIN}/',
- '/{VIADEO}/'
- );
-
- $replaces = array(
- $this->preferences->pref_nom,
- $this->preferences->pref_website,
- $this->preferences->pref_facebook,
- $this->preferences->pref_googleplus,
- $this->preferences->pref_twitter,
- $this->preferences->pref_linkedin,
- $this->preferences->pref_viadeo
- );
-
- $sign = preg_replace(
- $patterns,
- $replaces,
- $this->preferences->pref_mail_sign
- );
-
+ $signature = $this->preferences->getMailSignature();
+ if ($signature != '') {
if ($this->html) {
//we are sending html message
- $tsign = "\r\n-- \r\n" . $sign;
//apply email sign to text version
- $this->mail->AltBody .= $tsign;
+ $this->mail->AltBody .= $signature;
//then apply email sign to html version
$sign_style = 'color:grey;border-top:1px solid #ccc;margin-top:2em';
$hsign = '<div style="' . $sign_style . '">' .
- nl2br($sign) . '</div>';
+ nl2br($signature) . '</div>';
$this->mail->Body .= $hsign;
} else {
- $sign = "\r\n-- \r\n" . $sign;
- $this->mail->Body .= $sign;
+ $this->mail->Body .= $signature;
}
}
namespace Galette\Core;
use Galette\Entity\PaymentType;
+use Galette\Entity\Social;
+use Galette\Features\Replacements;
+use Galette\Features\Socials;
use Throwable;
use Analog\Analog;
use Galette\Entity\Adherent;
* @property boolean $pref_bool_publicpages
* @property integer $pref_publicpages_visibility
* @property boolean $pref_bool_selfsubscribe
- * @property string $pref_googleplus
- * @property string $pref_facebook
- * @property string $pref_twitter
- * @property string $pref_viadeo
- * @property string $pref_linkedin
* @property string $pref_mail_sign
* @property string $pref_new_contrib_script
* @property boolean $pref_bool_wrap_mails
*/
class Preferences
{
- private $zdb;
+ use Replacements;
+ use Socials;
+
+ protected $preferences; //redefined from Replacements feature - avoid circular dependency
private $prefs;
private $errors = [];
'pref_bool_publicpages' => true,
'pref_publicpages_visibility' => self::PUBLIC_PAGES_VISIBILITY_RESTRICTED,
'pref_bool_selfsubscribe' => true,
- 'pref_googleplus' => '',
- 'pref_facebook' => '',
- 'pref_twitter' => '',
- 'pref_viadeo' => '',
- 'pref_linkedin' => '',
- 'pref_mail_sign' => "{NAME}\r\n\r\n{WEBSITE}\r\n{GOOGLEPLUS}\r\n{FACEBOOK}\r\n{TWITTER}\r\n{LINKEDIN}\r\n{VIADEO}",
+ 'pref_mail_sign' => "{ASSO_NAME}\r\n\r\n{ASSO_WEBSITE}",
/* New contribution script */
'pref_new_contrib_script' => '',
'pref_bool_wrap_mails' => true,
'pref_bool_create_member' => false
);
+ /** @var Social[] */
+ private $socials;
+
// flagging required fields
private $required = array(
'pref_nom',
foreach ($result as $pref) {
$this->prefs[$pref->nom_pref] = $pref->val_pref;
}
+ $this->socials = Social::getListForMember(null);
return true;
} catch (Throwable $e) {
Analog::log(
}
}
+ $this->checkSocials($values);
+
return 0 === count($this->errors);
}
'Preferences were successfully stored into database.',
Analog::INFO
);
+
+ $this->storeSocials(null);
+
return true;
} catch (Throwable $e) {
$this->zdb->connection->rollBack();
} elseif (in_array($name, $virtuals)) {
$virtual = str_replace('vpref_', 'pref_', $name);
return explode(',', $this->prefs[$virtual]);
+ } elseif ($name === 'socials') {
+ return $this->socials;
} else {
Analog::log(
'Preference `' . $name . '` is not set or is forbidden',
{
return $this->errors;
}
+
+ /**
+ * Build legend array
+ *
+ * @return array
+ */
+ public function getLegend(): array
+ {
+ $legend = [];
+
+ $legend['main'] = [
+ 'title' => _T('Main information'),
+ 'patterns' => $this->getMainPatterns()
+ ];
+
+ $s_patterns = $this->getSignaturePatterns(false);
+ if (count($s_patterns)) {
+ $legend['socials'] = [
+ 'title' => _T('Social networks'),
+ 'patterns' => $this->getSignaturePatterns(false)
+ ];
+ }
+
+ return $legend;
+ }
+
+ /**
+ * Get email signature
+ *
+ * @return string
+ */
+ public function getMailSignature(): string
+ {
+ global $router;
+
+ $signature = $this->pref_mail_sign;
+
+ if (trim($signature) == '') {
+ return '';
+ }
+
+ $this->setPreferences($this)->setRouter($router);
+ $this->setPatterns(
+ $this->getMainPatterns() + $this->getSignaturePatterns()
+ );
+ $this
+ ->setMain()
+ ->setSocialReplacements();
+
+ $signature = $this->proceedReplacements($signature);
+
+ return "\r\n-- \r\n" . $signature;
+ }
+
+ /**
+ * Get patterns for mail signature
+ *
+ * @param boolean $legacy Whether to load legacy patterns
+ *
+ * @return array
+ */
+ protected function getSignaturePatterns($legacy = true): array
+ {
+ $s_patterns = [];
+ $social = new Social($this->zdb);
+
+ $types = $this->getCoreRegisteredTypes() + $social->getSystemTypes(false);
+
+ foreach ($types as $type) {
+ $s_patterns['asso_social_' . $type] = [
+ 'title' => $social->getSystemType($type),
+ 'pattern' => '/{ASSO_SOCIAL_' . strtoupper($type) . '}/'
+ ];
+ }
+
+ if ($legacy === true) {
+ $main = $this->getMainPatterns();
+ $s_patterns['_asso_name'] = [
+ 'title' => $main['asso_name']['title'],
+ 'pattern' => '/{NAME}/'
+ ];
+
+ $s_patterns['_asso_website'] = [
+ 'title' => $main['asso_website']['title'],
+ 'pattern' => '/{WEBSITE}/'
+ ];
+
+ foreach ([Social::FACEBOOK, Social::TWITTER, Social::LINKEDIN, Social::VIADEO] as $legacy_type) {
+ $s_patterns['_asso_social_' . $legacy_type] = [
+ 'title' => $s_patterns['asso_social_' . $legacy_type]['title'],
+ 'pattern' => '/{' . strtoupper($legacy_type) . '}/'
+ ];
+ }
+ }
+
+ return $s_patterns;
+ }
+
+ /**
+ * Set emails replacements
+ *
+ * @return $this
+ */
+ public function setSocialReplacements(): self
+ {
+ $replacements = [];
+
+ $done_replacements = $this->getReplacements();
+ $replacements['_asso_name'] = $done_replacements['asso_name'];
+ $replacements['asso_website'] = $this->pref_website;
+ $replacements['_asso_website'] = $replacements['asso_website'];
+
+ $social = new Social($this->zdb);
+ $types = $this->getCoreRegisteredTypes() + $social->getSystemTypes(false);
+
+ foreach ($types as $type) {
+ $replace_value = null;
+ $socials = Social::getListForMember(null, $type);
+ if (count($socials)) {
+ $replace_value = '';
+ foreach ($socials as $social) {
+ if ($replace_value != '') {
+ $replace_value .= ', ';
+ }
+ $replace_value .= $social->url;
+ }
+ }
+ $replacements['asso_social_' . strtolower($type)] = $replace_value;
+ }
+
+
+ foreach ([Social::FACEBOOK, Social::TWITTER, Social::LINKEDIN, Social::VIADEO] as $legacy_type) {
+ $replacements['_asso_social_' . $legacy_type] = $replacements['asso_social_' . $legacy_type];
+ }
+
+ $this->setReplacements($replacements);
+
+ return $this;
+ }
}
namespace Galette\Entity;
+use Galette\Features\Socials;
use Throwable;
use Analog\Analog;
use Laminas\Db\Sql\Expression;
* @property string $phone
* @property string $gsm
* @property string $email
- * @property string $website
- * @property string $msn
- * @property string $icq
- * @property string $jabber
* @property string $gnupgid
* @property string $fingerprint
* @property string $login
* @property string $contribstatus State of member contributions
* @property string $days_remaining
* @property-read integer $parent_id
+ * @property Social $social Social networks/Contact
+ *
*/
class Adherent
{
use Dynamics;
+ use Socials;
public const TABLE = 'adherents';
public const PK = 'id_adh';
private $_phone;
private $_gsm;
private $_email;
- private $_website;
- private $_msn; /** TODO: remove */
- private $_icq; /** TODO: remove */
- private $_jabber; /** TODO: remove */
private $_gnupgid;
private $_fingerprint;
//Galette relative information
private $_parent;
private $_children;
private $_duplicate = false;
+ private $_socials;
private $_row_classes;
'dues' => true,
'parent' => false,
'children' => false,
- 'dynamics' => false
+ 'dynamics' => false,
+ 'socials' => false
);
private $zdb;
$this->_phone = $r->tel_adh;
$this->_gsm = $r->gsm_adh;
$this->_email = $r->email_adh;
- $this->_website = $r->url_adh;
- /** TODO: remove */
- $this->_msn = $r->msn_adh;
- /** TODO: remove */
- $this->_icq = $r->icq_adh;
- /** TODO: remove */
- $this->_jabber = $r->jabber_adh;
- /** TODO: remove */
$this->_gnupgid = $r->gpgid;
- /** TODO: remove */
$this->_fingerprint = $r->fingerprint;
//Galette relative information
$this->_appears_in_list = ($r->bool_display_info == 1) ? true : false;
if ($this->_deps['dynamics'] === true) {
$this->loadDynamicFields();
}
+
+ if ($this->_deps['socials'] === true) {
+ $this->loadSocials();
+ }
}
/**
$this->_managed_groups = Groups::loadManagedGroups($this->_id);
}
+ /**
+ * Load member social network/contact information
+ *
+ * @return void
+ */
+ public function loadSocials()
+ {
+ $this->_socials = Social::getListForMember($this->_id);
+ }
+
/**
* Retrieve status from preferences
*
}
$this->dynamicsCheck($values, $required, $disabled);
+ $this->checkSocials($values);
if (count($this->errors) > 0) {
Analog::log(
}
break;
case 'email_adh':
- case 'msn_adh':
if (!GaletteMail::isValidEmail($value)) {
$this->errors[] = _T("- Non-valid E-Mail address!") .
' (' . $this->getFieldLabel($field) . ')';
}
}
break;
- case 'url_adh':
- if ($value == 'http://' || $value == 'https://') {
- $this->$prop = '';
- } elseif (!isValidWebUrl($value)) {
- $this->errors[] = _T("- Non-valid Website address! Maybe you've skipped the http://?");
- }
- break;
case 'login_adh':
/** FIXME: add a preference for login length */
if (strlen($value) < 2) {
//dynamic fields
if ($success) {
$success = $this->dynamicsStore();
+ $this->storeSocials($this->id);
}
//send event at the end of process, once all has been stored
$virtuals = array(
'sadmin', 'sstaff', 'sdue_free', 'sappears_in_list', 'sactive',
'stitle', 'sstatus', 'sfullname', 'sname', 'saddress',
- 'rbirthdate', 'sgender', 'contribstatus'
+ 'rbirthdate', 'sgender', 'contribstatus',
);
+ $socials = array('website', 'msn', 'jabber', 'icq');
+
if (in_array($name, $forbidden)) {
switch ($name) {
case 'admin':
}
}
+ //for backward compatibility
+ if (in_array($name, $socials)) {
+ $values = Social::getListForMember($this->_id, $name);
+ return $values[0] ?? null;
+ }
+
if (substr($name, 0, 1) !== '_') {
$rname = '_' . $name;
} else {
--- /dev/null
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Social networks/Contacts
+ *
+ * PHP version 5
+ *
+ * Copyright © 2021 The Galette Team
+ *
+ * This file is part of Galette (http://galette.tuxfamily.org).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Entity
+ * @package Galette
+ *
+ * @author Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2021 The Galette Team
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link http://galette.tuxfamily.org
+ * @since Available since 0.9.6dev - 2021-10-23
+ */
+
+namespace Galette\Entity;
+
+use Galette\Core\GaletteMail;
+use Galette\Features\I18n;
+use Laminas\Db\ResultSet\ResultSet;
+use Laminas\Db\Sql\Expression;
+use Throwable;
+use Galette\Core\Db;
+use Analog\Analog;
+
+/**
+ * Social networks/Contacts
+ *
+ * @category Entity
+ * @name Social
+ * @package Galette
+ * @author Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2021 The Galette Team
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link http://galette.tuxfamily.org
+ * @since Available since 0.9.6dev - 2021-10-23
+ */
+
+class Social
+{
+ use I18n;
+
+ public const TABLE = 'socials';
+ public const PK = 'id_social';
+
+ public const MASTODON = 'mastodon';
+ public const TWITTER = 'twitter';
+ public const FACEBOOK = 'facebook';
+ public const LINKEDIN = 'linkedin';
+ public const VIADEO = 'viadeo';
+ public const JABBER = 'jabber';
+ public const ICQ = 'icq';
+ public const WEBSITE = 'website';
+ public const BLOG = 'blog';
+
+ /** @var Db */
+ private $zdb;
+ /** @var int */
+ private $id;
+ /** @var string */
+ private $type;
+ /** @var string */
+ private $url;
+ /** @var int */
+ private $id_adh;
+ /** @var Adherent */
+ private $member;
+
+ /**
+ * Main constructor
+ *
+ * @param Db $zdb Database instance
+ * @param mixed $args Arguments
+ */
+ public function __construct(Db $zdb, $args = null)
+ {
+ $this->zdb = $zdb;
+ if (is_int($args)) {
+ $this->load($args);
+ } elseif (is_object($args)) {
+ $this->loadFromRs($args);
+ }
+ }
+
+ /**
+ * Load a social from its identifier
+ *
+ * @param integer $id Identifier
+ *
+ * @return void
+ */
+ private function load(int $id): void
+ {
+ try {
+ $select = $this->zdb->select(self::TABLE);
+ $select->limit(1)->where(self::PK . ' = ' . $id);
+
+ $results = $this->zdb->execute($select);
+ $res = $results->current();
+ $this->loadFromRs($res);
+ } catch (Throwable $e) {
+ Analog::log(
+ 'An error occurred loading social #' . $id . "Message:\n" .
+ $e->getMessage(),
+ Analog::ERROR
+ );
+ }
+ }
+
+ /**
+ * Get socials for a member
+ *
+ * @param int|null $id_adh Member id
+ * @param string|null $type Type to retrieve
+ *
+ * @return array
+ *
+ * @throws Throwable
+ */
+ public static function getListForMember(int $id_adh = null, string $type = null): array
+ {
+ global $zdb;
+
+ try {
+ $select = $zdb->select(self::TABLE);
+
+ if ($id_adh === null) {
+ $select->where(Adherent::PK . ' IS NULL');
+ } else {
+ $select->where([Adherent::PK => $id_adh]);
+ }
+
+ if ($type !== null) {
+ $select->where(['type' => $type]);
+ }
+
+ $select->order(self::PK);
+
+ $results = $zdb->execute($select);
+ $socials = [];
+ foreach ($results as $r) {
+ $socials[$r->{self::PK}] = new Social($zdb, $r);
+ }
+ return $socials;
+ } catch (Throwable $e) {
+ Analog::log(
+ 'An error occurred loading socials for member #' . $id_adh . "Message:\n" .
+ $e->getMessage(),
+ Analog::ERROR
+ );
+ throw $e;
+ }
+ }
+
+ /**
+ * Load social from a db ResultSet
+ *
+ * @param ResultSet $rs ResultSet
+ *
+ * @return void
+ */
+ private function loadFromRs($rs)
+ {
+ $this->id = $rs->{self::PK};
+ $this->setLinkedMember((int)$rs->{Adherent::PK});
+ $this->type = $rs->type;
+ $this->url = $rs->url;
+ }
+
+ /**
+ * Store social in database
+ *
+ * @return boolean
+ */
+ public function store(): bool
+ {
+ try {
+ if ($this->id !== null && $this->id > 0) {
+ $update = $this->zdb->update(self::TABLE);
+ $update->set(['url' => $this->url])->where(
+ self::PK . '=' . $this->id
+ );
+ $this->zdb->execute($update);
+ } else {
+ $insert = $this->zdb->insert(self::TABLE);
+ $id_adh = $this->{Adherent::PK} > 0 ? $this->{Adherent::PK} : new Expression('NULL');
+ $insert->values([
+ 'type' => $this->type,
+ 'url' => $this->url,
+ Adherent::PK => $id_adh
+ ]);
+ $add = $this->zdb->execute($insert);
+ if (!$add->count() > 0) {
+ Analog::log('Not stored!', Analog::ERROR);
+ return false;
+ }
+
+ $this->id = $this->zdb->getLastGeneratedValue($this);
+ if (!in_array($this->type, $this->getSystemTypes(false))) {
+ $this->addTranslation($this->type);
+ }
+ }
+ return true;
+ } catch (Throwable $e) {
+ Analog::log(
+ 'An error occurred storing social: ' . $e->getMessage(),
+ Analog::ERROR
+ );
+ throw $e;
+ }
+ }
+
+ /**
+ * Remove current social
+ *
+ * @param array|null $ids IDs to remove, default to current id
+ *
+ * @return boolean
+ */
+ public function remove(array $ids = null): bool
+ {
+ if ($ids == null) {
+ $ids[] = $this->id;
+ }
+
+ try {
+ $delete = $this->zdb->delete(self::TABLE);
+ $delete->where([self::PK => $ids]);
+ $this->zdb->execute($delete);
+ Analog::log(
+ 'Social #' . implode(', #', $ids) . ' deleted successfully.',
+ Analog::INFO
+ );
+ return true;
+ } catch (Throwable $e) {
+ Analog::log(
+ 'Unable to delete social #' . implode(', #', $ids) . ' | ' . $e->getMessage(),
+ Analog::ERROR
+ );
+ throw $e;
+ }
+ }
+
+ /**
+ * Getter
+ *
+ * @param string $name Property name
+ *
+ * @return mixed
+ */
+ public function __get(string $name)
+ {
+ return $this->$name;
+ }
+
+ /**
+ * Display URL the best way
+ *
+ * @return string
+ */
+ public function displayUrl(): string
+ {
+ if (isValidWebUrl($this->url)) {
+ return sprintf('<a href="%1$s">%1$s</a>', $this->url);
+ }
+
+ if (GaletteMail::isValidEmail($this->url)) {
+ return sprintf('<a href="mailto:%1$s">%1$s</a>', $this->url);
+ }
+
+ return $this->url;
+ }
+
+ /**
+ * Set type
+ *
+ * @param string $type Type
+ *
+ * @return $this
+ */
+ public function setType(string $type): self
+ {
+ $this->type = $type;
+ return $this;
+ }
+
+ /**
+ * Set linked member
+ *
+ * @param int|null $id Member id
+ *
+ * @return $this
+ */
+ public function setLinkedMember(int $id = null): self
+ {
+ $this->{Adherent::PK} = $id;
+ if ($this->{Adherent::PK} > 0) {
+ $this->member = new Adherent($this->zdb, $this->{Adherent::PK});
+ }
+ return $this;
+ }
+
+ /**
+ * Set URL
+ *
+ * @param string $url Value to set
+ *
+ * @return $this
+ */
+ public function setUrl(string $url): self
+ {
+ $this->url = $url;
+ return $this;
+ }
+
+ /**
+ * Get system social types
+ *
+ * @param boolean $translated Return translated types (default) or not
+ *
+ * @return array
+ */
+ public function getSystemTypes(bool $translated = true): array
+ {
+ if ($translated) {
+ $systypes = [
+ self::MASTODON => _T('Mastodon'),
+ self::TWITTER => _T('Twitter'),
+ self::FACEBOOK => _T('Facebook'),
+ self::LINKEDIN => _T('LinkedIn'),
+ self::VIADEO => _T('Viadeo'),
+ self::JABBER => _T('Jabber'),
+ self::ICQ => _T('ICQ'),
+ self::WEBSITE => _T('Website'),
+ self::BLOG => _T('Blog')
+ ];
+ } else {
+ $systypes = [
+ self::MASTODON => 'mastodon',
+ self::TWITTER => 'twitter',
+ self::FACEBOOK => 'facebook',
+ self::LINKEDIN => 'linkedin',
+ self::VIADEO => 'viadeo',
+ self::JABBER => 'jabber',
+ self::ICQ => 'icq',
+ self::WEBSITE => 'website',
+ self::BLOG => 'blog'
+ ];
+ }
+ return $systypes;
+ }
+
+ /**
+ * Get system social types
+ *
+ * @param string $type Social type
+ * @param boolean $translated Return translated types (default) or not
+ *
+ * @return string
+ */
+ public function getSystemType(string $type, bool $translated = true): string
+ {
+ return $this->getSystemTypes($translated)[$type] ?? _T($type);
+ }
+}
--- /dev/null
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Socials feature
+ *
+ * PHP version 5
+ *
+ * Copyright © 2021 The Galette Team
+ *
+ * This file is part of Galette (http://galette.tuxfamily.org).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Entity
+ * @package Galette
+ *
+ * @author Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2021 The Galette Team
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link https://galette.eu
+ * @since 2021-10-25
+ */
+
+namespace Galette\Features;
+
+use Galette\Entity\Adherent;
+use Galette\Entity\Social;
+
+/**
+ * Replacements feature
+ *
+ * @category Features
+ * @name Replacements
+ * @package Galette
+ * @author Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2020-2021 The Galette Team
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link http://galette.eu
+ * @since 2020-12-20
+ */
+
+trait Socials
+{
+ protected $socials_input = [];
+
+ /**
+ * Check socials
+ *
+ * @param array $post User input
+ *
+ * @return void
+ */
+ protected function checkSocials(array $post)
+ {
+ $this->socials_input = [];
+ foreach ($post as $key => $value) {
+ if (str_starts_with($key, 'social_')) {
+ $this->socials_input[$key] = $value;
+ }
+ }
+ }
+
+ /**
+ * Store social networks/contacts
+ *
+ * @param int|null $id ID
+ *
+ * @return bool
+ */
+ protected function storeSocials(int $id = null): bool
+ {
+ $existings = Social::getListForMember($id);
+ foreach ($this->socials_input as $key => $value) {
+ if (
+ str_starts_with($key, 'social_new_type')
+ && !empty($value)
+ && isset($this->socials_input[str_replace('_type', '_value', $key)])
+ && !empty($this->socials_input[str_replace('_type', '_value', $key)])
+ ) {
+ //new social network
+ $new_index = (int)str_replace('social_new_type_', '', $key);
+ $social = new Social($this->zdb);
+ $social
+ ->setType($value)
+ ->setLinkedMember($id)
+ ->setUrl($this->socials_input['social_new_value_' . $new_index])
+ ->store();
+ } elseif (str_starts_with($key, 'social_') && !str_starts_with($key, 'social_new_')) {
+ //existing social network
+ $social_id = (int)str_replace('social_', '', $key);
+ $social = $existings[$social_id];
+ if ($value != $social->url) {
+ $social
+ ->setUrl($value)
+ ->store();
+ }
+ unset($existings[$social_id]);
+ }
+ }
+
+ if (count($existings)) {
+ $social = new Social($this->zdb);
+ $social->remove(array_keys($existings));
+ }
+
+ return true;
+ }
+
+ /**
+ * Get core registered types
+ * @return array
+ */
+ protected function getCoreRegisteredTypes(): array
+ {
+ return $this->getRegisteredTypes(true);
+ }
+
+ /**
+ * Get member registered types
+ *
+ * @return array
+ */
+ public function getMemberRegisteredTypes(): array
+ {
+ return $this->getRegisteredTypes(false);
+ }
+
+ /**
+ * Get registered types
+ *
+ * @param bool $core True for core type, false for members ones
+ *
+ * @return array
+ */
+ protected function getRegisteredTypes(bool $core): array
+ {
+ $select = $this->zdb->select(Social::TABLE, 's');
+ $select->quantifier('DISTINCT')->columns(['type']);
+ if ($core === true) {
+ $select->where(Adherent::PK . ' IS NULL');
+ } else {
+ $select->where(Adherent::PK . ' IS NOT NULL');
+ }
+
+ $results = $this->zdb->execute($select);
+ $types = [];
+ foreach ($results as $result) {
+ $types[$result->type] = $result->type;
+ }
+
+ return $types;
+ }
+}
'tel_adh',
'gsm_adh',
'email_adh',
- 'url_adh',
'prof_adh',
'pseudo_adh',
'societe_adh',
*
* PHP version 5
*
- * Copyright © 2014 The Galette Team
+ * Copyright © 2021 The Galette Team
*
* This file is part of Galette (http://galette.tuxfamily.org).
*
* @package Galette
*
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2014 The Galette Team
+ * @copyright 2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since Available since 0.8.2dev - 2014-11-30
* @package Galette
* @abstract Class for expanding TCPDF.
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2014 The Galette Team
+ * @copyright 2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since Available since 0.8.2dev - 2014-11-30
$this->nbcol = self::getCols();
// Number of rows
$this->nbrow = self::getRows();
- // Spacing betweeen cards
+ // Spacing between cards
$this->hspacing = $this->preferences->pref_card_hspace;
$this->vspacing = $this->preferences->pref_card_vspace;
case 0:
$email .= $member->email;
break;
- case 1:
- $email .= $member->msn;
- break;
- case 2:
- $email .= $member->jabber;
- break;
- case 3:
- $email .= $member->website;
- break;
- case 4:
- $email .= $member->icq;
- break;
case 5:
$email .= $member->zipcode . ' - ' . $member->town;
break;
namespace Galette\Repository;
+use Galette\Entity\Social;
use Throwable;
use Galette\DynamicFields\DynamicField;
use Galette\Entity\DynamicFieldsHandle;
array('p' => PREFIX_DB . Status::TABLE),
'a.' . Status::PK . '=p.' . Status::PK,
array()
+ )->join(
+ array('so' => PREFIX_DB . Social::TABLE),
+ 'a.' . Adherent::PK . '=so.' . Adherent::PK,
+ array(),
+ $select::JOIN_LEFT
);
break;
case self::SHOW_EXPORT:
$select->join(
array('p' => PREFIX_DB . Status::TABLE),
'a.' . Status::PK . '=p.' . Status::PK
+ )->join(
+ array('so' => PREFIX_DB . Social::TABLE),
+ 'a.' . Adherent::PK . '=so.' . Adherent::PK,
+ array(),
+ $select::JOIN_LEFT
)->join(
array('gr' => PREFIX_DB . Group::GROUPSUSERS_TABLE),
'a.' . Adherent::PK . '=gr.' . Adherent::PK,
'(' .
'LOWER(email_adh) LIKE ' . $token
. ' OR ' .
- 'LOWER(url_adh) LIKE ' . $token
- . ' OR ' .
- 'LOWER(msn_adh) LIKE ' . $token
- . ' OR ' .
- 'LOWER(icq_adh) LIKE ' . $token
- . ' OR ' .
- 'LOWER(jabber_adh) LIKE ' . $token
+ 'LOWER(so.url) LIKE ' . $token
. ')'
);
break;
$fs['field'] = 'val';
}
+ //handle socials networks
+ if (strpos($fs['field'], 'socials_') === 0) {
+ //social networks
+ $type = str_replace('socials_', '', $fs['field']);
+ $prefix = 'so.';
+ $fs['field'] = 'url';
+ $select->where(['so.type' => $type]);
+ }
+
if ($dyn_field && $dyn_field instanceof \Galette\DynamicFields\Boolean) {
if ($fs['search'] != 0) {
$qry .= $prefix . $fs['field'] . $qop . ' ' .
{/if}
<option value="dyn_{$field->getId()}"{if $fs.field eq $rid} selected="selected"{/if}>{$field->getName()}</option>
{/foreach}
+ {foreach from=$adh_socials item=$label key=$type}
+ {assign var=rid value="socials_$type"}
+ {if $fs.field eq $rid}
+ {assign var=cur_field value=$type}
+ {/if}
+ <option value="socials_{$type}"{if $fs.field eq $rid} selected="selected"{/if}>{$label}</option>
+ {/foreach}
+
</select>
{* may not be defined *}
{if !isset($cur_field)}{assign var=cur_field value=null}{/if}
--- /dev/null
+{if $socials|@count > 0}
+ <table class="details" id="social">
+ <caption class="ui-state-active ui-corner-top">{_T string="Social networks"}</caption>
+ {foreach item=social from=$socials}
+ <tr>
+ <th>{$social->getSystemType($social->type)}</th>
+ <td>{$social->displayUrl()}</td>
+ </tr>
+ {/foreach}
+ </table>
+{/if}
--- /dev/null
+<fieldset class="{if isset($social_fieldset_class)}{$social_fieldset_class}{else}cssform{/if}" id="social">
+ <legend{if isset($social_fieldset_legend_class)} class="{$social_fieldset_legend_class}"{/if}>{_T string="Social networks"}</legend>
+ <div>
+ {foreach item=social from=$socials}
+ <p>
+ <label for="social_{$social->id}" class="bline">{$social->getSystemType($social->type)}</label>
+ <span>
+ <input type="text" name="social_{$social->id}" id="social_{$social->id}" value="{$social->url}" class="large"/>
+ <a href="#" class="fright tooltip delete delsocial">
+ <i class="fas fa-trash-alt"></i>
+ <span class="sr-only">{_T string="Remove %type" pattern="/%type/" replace=$social->getSystemType($social->type)}</span>
+ </a>
+ </span>
+ </p>
+ {/foreach}
+ <p>
+ <span class="bline">{_T string="Add new social network"}</span>
+ <span>
+ <select name="social_new_type_1" id="social_new_type_1" class="nochosen socials_selector">
+ <option value="">{_T string="Choose or enter your own..."}</option>
+ {foreach item=social_type from=$osocials->getSystemTypes(false)}
+ <option value="{$social_type}">{$osocials->getSystemType($social_type)}</option>
+ {/foreach}
+ </select>
+ <input type="text" name="social_new_value_1" id="social_new_value_1" value="" size="50"/>
+ <a href="#" class="fright tooltip action addsocial">
+ <i class="fas fa-plus-square"></i>
+ <span class="sr-only">{_T string="Add"}</span>
+ </a>
+ </span>
+ <script type="text/javascript">
+ var _selectize = function(selector) {
+ if ( !selector ) {
+ selector = '.socials_selector';
+ }
+
+ $(selector).selectize({
+ maxItems: 1,
+ create: true,
+ createOnBlur: true
+ });
+ }
+
+ $('.addsocial').click(function(e){
+ e.preventDefault();
+ $('.socials_selector').each(function(){ // do this for every select with the 'combobox' class
+ var _this = $(this);
+ if (_this[0].selectize) { // requires [0] to select the proper object
+ var value = $(this).val(); // store the current value of the select/input
+ _this[0].selectize.destroy(); // destroys selectize()
+ _this.val(value); // set back the value of the select/input
+ }
+ });
+
+ var _newindex = $(this).parents('fieldset').find('p:last select').attr('id').replace('social_new_type_', '');
+ ++_newindex;
+ $(this).parents('p')
+ .clone() // copy
+ .insertAfter('#social p:last') // where
+ .find('select').attr('id', 'social_new_type_' + _newindex).attr('name', 'social_new_type_' + _newindex)
+ .parent().find('input').attr('id', 'social_new_value_' + _newindex).attr('name', 'social_new_value_' + _newindex)
+ .parent().find('.addsocial').remove()
+ ;
+
+ _selectize();
+ });
+
+ var _rmFilter = function(elt) {
+ if ( typeof elt == 'undefined') {
+ elt = $('#social p');
+ }
+ elt.find('.delsocial').click(function(e){
+ e.preventDefault();
+ var _this = $(this);
+ _this.parents('p').remove();
+ });
+ }
+ _rmFilter();
+ _selectize();
+ </script>
+ </p>
+ </div>
+</fieldset>
\ No newline at end of file
{if $entry->field_id eq 'gpgid'}
{assign var="size" value="8"}
{/if}
- {if $entry->field_id eq 'email_adh'
- or $entry->field_id eq 'msn_adh'
- or $entry->field_id eq 'jabber_adh'
- or $entry->field_id eq 'url_adh'}
+ {if $entry->field_id eq 'email_adh'}
{assign var="size" value="30"}
{/if}
{if $entry->field_id eq 'fingerprint'}
{/if}
{if $entry->field_id eq 'bool_display_info'}
{assign var="title" value={_T string="Do member want to appear publically?"}}
- {assign var="tip" value={_T string="If you check this box (and if you are up to date with your contributions), your full name, website address ad other information will be publically visible on the members list.<br/>If you've uploaded a photo, it will be displayed on the trombinoscope page.<br/>Note that administrators can disabled public pages, this setting will have no effect in that case."}}
+ {assign var="tip" value={_T string="If you check this box (and if you are up to date with your contributions), your full name and other information will be publically visible on the members list.<br/>If you've uploaded a photo, it will be displayed on the trombinoscope page.<br/>Note that administrators can disabled public pages, this setting will have no effect in that case."}}
{assign var="checked" value=$member->appearsInMembersList()}
{/if}
{if $entry->field_id eq 'login_adh'}
{else}
<img src="{base_url}/{$template_subdir}images/icon-empty.png" alt="" width="16" height="16"/>
{/if}
- {if $member->website != ''}
- <a href="{$member->website}" class="tooltip">
- <img src="{base_url}/{$template_subdir}images/icon-website.png" alt="" width="16" height="16"/>
- <span class="sr-only">{_T string="Website"}<span>
- </a>
- {else}
- <img src="{base_url}/{$template_subdir}images/icon-empty.png" alt="" width="16" height="16"/>
- {/if}
{if $member->isAdmin()}
<span class="tooltip">
<img src="{base_url}/{$template_subdir}images/icon-star.png" alt="" width="16" height="16"/>
but for notw, that works as excpected.
*}
{if not empty($value)}
- {if $column->field_id eq 'email_adh' or $column->field_id eq 'msn_adh'}
+ {if $column->field_id eq 'email_adh'}
<a href="mailto:{$value}">{$value}</a>
{elseif $column->field_id eq 'tel_adh' or $column->field_id eq 'gsm_adh'}
<a href="tel:{$value}">{$value}</a>
- {elseif $column->field_id eq 'url_adh'}
- <a href="{$value}">{$value}</a>
{elseif $column->field_id eq 'parent_id'}
<a href="{path_for name="member" data=["id" => $member->parent]}">{memberName id=$member->parent}</a>
{elseif $column->field_id eq 'ddn_adh'}
<tr>
<th><img src="{base_url}/{$template_subdir}images/icon-mail.png" alt="{_T string="Mail"}" width="16" height="16"/></th>
<td class="back">{_T string="Send an email"}</td>
- <th><img src="{base_url}/{$template_subdir}images/icon-website.png" alt="{_T string="Website"}" width="16" height="16"/></th>
- <td class="back">{_T string="Visit website"}</td>
+ <th><img src="{base_url}/{$template_subdir}images/icon-company.png" alt="{_T string="Is a company"}" width="16" height="16"/></th>
+ <td class="back">{_T string="Is a company"}</td>
</tr>
<tr>
<th><img src="{base_url}/{$template_subdir}images/icon-female.png" alt="{_T string="Is a woman"}" width="16" height="16"/></th>
<td class="back">{_T string="Is a woman"}</td>
</tr>
- <tr>
- <th><img src="{base_url}/{$template_subdir}images/icon-company.png" alt="{_T string="Is a company"}" width="16" height="16"/></th>
- <td class="back">{_T string="Is a company"}</td>
- </tr>
<tr>
<th><img src="{base_url}/{$template_subdir}images/icon-star.png" alt="{_T string="Admin"}" width="16" height="16"/></th>
<td class="back">{_T string="Admin"}</td>
{* Dynamic entries *}
{include file="edit_dynamic_fields.tpl" object=$member}
+ {include file="edit_socials.tpl" socials=$member->socials social_fieldset_class="galette_form" social_fieldset_legend_class="ui-state-active ui-corner-top"}
+
<p>
{if !$member->id && !$self_adh}
{if ($login->isAdmin() or $login->isStaff())}
</fieldset>
- <fieldset class="cssform" id="social">
- <legend>{_T string="Social networks"}</legend>
- <p>
- <label for="pref_googleplus" class="bline">{_T string="Google+"}</label>
- <input type="text" name="pref_googleplus" id="pref_googleplus" value="{$pref.pref_googleplus}" class="large"/>
- </p>
- <p>
- <label for="pref_facebook" class="bline">{_T string="Facebook"}</label>
- <input type="text" name="pref_facebook" id="pref_facebook" value="{$pref.pref_facebook}" class="large"/>
- </p>
- <p>
- <label for="pref_twitter" class="bline">{_T string="Twitter"}</label>
- <input type="text" name="pref_twitter" id="pref_twitter" value="{$pref.pref_twitter}" class="large"/>
- </p>
- <p>
- <label for="pref_linkedin" class="bline">{_T string="LinkedIn"}</label>
- <input type="text" name="pref_linkedin" id="pref_linkedin" value="{$pref.pref_linkedin}" class="large"/>
- </p>
- <p>
- <label for="pref_viadeo" class="bline">{_T string="Viadeo"}</label>
- <input type="text" name="pref_viadeo" id="pref_viadeo" value="{$pref.pref_viadeo}" class="large"/>
- </p>
- </fieldset>
+ {assign var="socials" value=$preferences->socials}
+ {include file="edit_socials.tpl"}
<fieldset class="cssform" id="parameters">
<legend>{_T string="Galette's parameters"}</legend>
<input type="password" name="pref_mail_smtp_password" id="pref_mail_smtp_password" value="{$pref.pref_mail_smtp_password}" autocomplete="off" maxlength="100" size="30"{if isset($required.pref_mail_smtp_password) and $required.pref_mail_smtp_password eq 1} required="required"{/if}/>
</p>
</div>
- <p>
+ <p id="mail_sign">
<label for="pref_mail_sign" class="bline tooltip vtop">{_T string="Mail signature"}</label>
<span class="tip">{_T string="The text that will be automatically set as signature for all outgoing emails.<br/>Variables are quoted with braces, are upper case, and will be replaced automatically.<br/>Refer to the doc to know what variables ara available. "}</span>
<textarea name="pref_mail_sign" id="pref_mail_sign">{$pref.pref_mail_sign}</textarea>
<label for="pref_card_address" class="bline">{_T string="Address type:"}</label>
<select name="pref_card_address" id="pref_card_address">
<option value="0" {if $pref.pref_card_address eq 0}selected="selected"{/if}>{_T string="Email"}</option>
- <option value="1" {if $pref.pref_card_address eq 1}selected="selected"{/if}>{_T string="MSN"}</option>
- <option value="2" {if $pref.pref_card_address eq 2}selected="selected"{/if}>{_T string="Jabber"}</option>
- <option value="3" {if $pref.pref_card_address eq 3}selected="selected"{/if}>{_T string="Web Site"}</option>
- <option value="4" {if $pref.pref_card_address eq 4}selected="selected"{/if}>{_T string="ICQ"}</option>
<option value="5" {if $pref.pref_card_address eq 5}selected="selected"{/if}>{_T string="Zip - Town"}</option>
<option value="6" {if $pref.pref_card_address eq 6}selected="selected"{/if}>{_T string="Nickname"}</option>
<option value="7" {if $pref.pref_card_address eq 7}selected="selected"{/if}>{_T string="Profession"}</option>
<em>* {_T string="None"}</em> {_T string="for no strength enforcement"}<br/>
<em>* {_T string="Weak"}</em> {_T string="require at least one matched rule"}<br/>
<em>* {_T string="Medium"}</em> {_T string="require at least two matched rules"}<br/>
- <em>* {_T string="Strong"}</em> {_T string="require at least three matched rules (recommended for most usages)"}</br/>
+ <em>* {_T string="Strong"}</em> {_T string="require at least three matched rules (recommended for most usages)"}<br/>
<em>* {_T string="Very Strong"}</em> {_T string="requires all rules."}<br/><br/>
{_T string="Rules include lower case characters, upper case characters, numbers, and special characters."}<br/><br/>
{_T string="Note that with any enforcement level, user cannot use his personal information (name, login, ...) as password."}
</form>
{include file="telemetry.tpl" part="dialog"}
+ {include file="replacements_legend.tpl" legends=$preferences->getLegend() cur_ref='prefs'}
{/block}
{block name="javascripts"}
});
});
+ _addLegenButton('#mail_sign');
+ _handleLegend();
+
{include file="js_pwdcheck.tpl" selector="#pref_admin_pass"}
{include file="js_pwdcheck.tpl" selector="#test_password_strength" extra_data="pref_password_length: \$('#pref_password_length').val(),pref_password_blacklist: \$('#pref_password_blacklist').is(':checked'),pref_password_strength: \$('#pref_password_strength').val(),"}
<i class="fas fa-venus fa-fw"></i>
{/if}
{/if}
- {if $element->field_id eq 'email_adh' or $element->field_id eq 'msn_adh'}
+ {if $element->field_id eq 'email_adh'}
<a href="mailto:{$value}">{$value}</a>
{elseif $element->field_id eq 'tel_adh' or $element->field_id eq 'gsm_adh'}
<a href="tel:{$value}">{$value}</a>
- {elseif $element->field_id eq 'url_adh'}
- <a href="{$value}">{$value}</a>
{elseif $element->field_id eq 'ddn_adh'}
{$value} {$member->getAge()}
{else}
{/foreach}
{include file="display_dynamic_fields.tpl" object=$member}
+{include file="display_socials.tpl" socials=$member->socials}
+
<a href="#" id="back2top">{_T string="Back to top"}</a>
</div>
{/block}
font-size:1.1em;
}
+p#mail_sign {
+ position: relative;
+}
+
/* =/ Main Galette styles */
/* == Groups stuff */
*
* PHP version 5
*
- * Copyright © 2013-2014 The Galette Team
+ * Copyright © 2013-2021 The Galette Team
*
* This file is part of Galette (http://galette.tuxfamily.org).
*
* @package GaletteTests
*
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2013-2014 The Galette Team
+ * @copyright 2013-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @version SVN: $Id$
* @link http://galette.tuxfamily.org
* @name Db
* @package GaletteTests
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2013-2014 The Galette Team
+ * @copyright 2013-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since 2013-02-05
'galette_types_cotisation',
'galette_paymenttypes',
'galette_database',
+ 'galette_socials',
'galette_statuts',
'galette_texts',
'galette_logs',
'0.93' => 'upgrade-to-0.93-pgsql.sql',
'0.931' => 'upgrade-to-0.931-pgsql.sql',
'0.94' => 'upgrade-to-0.94-pgsql.sql',
- '0.95' => 'upgrade-to-0.95-pgsql.sql'
+ '0.95' => 'upgrade-to-0.95-pgsql.sql',
+ '0.96' => 'upgrade-to-0.96-pgsql.sql'
);
$this->array($update_scripts)
'pseudo_adh' => 'elisabeth50',
'pays_adh' => 'Géorgie',
'tel_adh' => '05 05 20 88 04',
- 'url_adh' => 'http://www.gay.com/tempora-nemo-quidem-laudantium-dolores',
'activite_adh' => true,
'id_statut' => 6,
'date_crea_adh' => '2019-09-02',
{
private $preferences = null;
private $zdb;
+ private $login;
+ private $mocked_router;
/**
* Set up tests
*/
public function beforeTestMethod($method)
{
- $this->zdb = new \Galette\Core\Db();
- $this->preferences = new \Galette\Core\Preferences(
- $this->zdb
- );
+ $this->mocked_router = new \mock\Slim\Router();
+ $this->calling($this->mocked_router)->pathFor = function ($name, $params) {
+ return $name;
+ };
+
+ $app = new \Galette\Core\SlimApp();
+ $plugins = new \Galette\Core\Plugins();
+ require GALETTE_BASE_PATH . '/includes/dependencies.php';
+ $container = $app->getContainer();
+ $_SERVER['HTTP_HOST'] = '';
+
+ $this->zdb = $container->get('zdb');
+ $this->login = $container->get('login');
+ $this->preferences = $container->get('preferences');
+ $container->set('router', $this->mocked_router);
+ $container->set(Slim\Router::class, $this->mocked_router);
+
+ global $router;
+ $router = $this->mocked_router;
}
/**
if (TYPE_DB === 'mysql') {
$this->array($this->zdb->getWarnings())->isIdenticalTo([]);
}
+
+ $delete = $this->zdb->delete(\Galette\Entity\Social::TABLE);
+ $this->zdb->execute($delete);
}
/**
$delete = $this->zdb->delete(\Galette\Core\Preferences::TABLE);
$delete->where(
array(
- \Galette\Core\Preferences::PK => 'pref_facebook'
+ \Galette\Core\Preferences::PK => 'pref_footer'
)
);
$this->zdb->execute($delete);
$delete = $this->zdb->delete(\Galette\Core\Preferences::TABLE);
$delete->where(
array(
- \Galette\Core\Preferences::PK => 'pref_viadeo'
+ \Galette\Core\Preferences::PK => 'pref_new_contrib_script'
)
);
$this->zdb->execute($delete);
$this->preferences->load();
- $fb = $this->preferences->pref_facebook;
- $viadeo = $this->preferences->pref_viadeo;
+ $footer = $this->preferences->pref_footer;
+ $new_contrib_script = $this->preferences->pref_new_contrib_script;
- $this->boolean($fb)->isFalse();
- $this->boolean($viadeo)->isFalse();
+ $this->boolean($footer)->isFalse();
+ $this->boolean($new_contrib_script)->isFalse();
$prefs = new \Galette\Core\Preferences($this->zdb);
- $fb = $prefs->pref_facebook;
- $viadeo = $prefs->pref_viadeo;
+ $footer = $prefs->pref_footer;
+ $new_contrib_script = $prefs->pref_new_contrib_script;
- $this->variable($fb)->isIdenticalTo('');
- $this->variable($viadeo)->isIdenticalTo('');
+ $this->variable($footer)->isIdenticalTo('');
+ $this->variable($new_contrib_script)->isIdenticalTo('');
}
/**
$this->preferences->$prop = $color;
$this->string($this->preferences->$prop)->isIdenticalTo($expected);
}
+
+ /**
+ * Test social networks
+ *
+ * @return void
+ */
+ public function testSocials()
+ {
+ $preferences = [];
+ foreach ($this->preferences->getDefaults() as $key => $value) {
+ $preferences[$key] = $value;
+ }
+
+ $preferences = array_merge($preferences, [
+ 'pref_nom' => 'Galette',
+ 'pref_ville' => 'Avignon',
+ 'pref_cp' => '84000',
+ 'pref_adresse' => 'Palais des Papes',
+ 'pref_adresse2' => 'Au milieu',
+ 'pref_pays' => 'France'
+ ]);
+
+ //will create 2 social networks in table
+ $post = [
+ 'notasocial' => 'notasocial', //must be ignored
+ 'social_new_type_1' => \Galette\Entity\Social::MASTODON,
+ 'social_new_value_1' => 'Galette mastodon URL',
+ 'social_new_type_2' => \Galette\Entity\Social::JABBER,
+ 'social_new_value_2' => 'Galette jabber ID',
+ 'social_new_type_3' => \Galette\Entity\Social::FACEBOOK,
+ 'social_new_value_3' => '', //empty value, no entry
+ 'social_new_type_4' => \Galette\Entity\Social::BLOG, //no value, no entry
+ ];
+
+ $post = array_merge($preferences, $post);
+
+ $this->boolean($this->preferences->check($post, $this->login))->isTrue(print_r($this->preferences->getErrors(), true));
+ $this->boolean($this->preferences->store())->isTrue();
+
+ $socials = \Galette\Entity\Social::getListForMember(null);
+ $this->array($socials)->hasSize(2);
+
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::MASTODON))->hasSize(1);
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::JABBER))->hasSize(1);
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::FACEBOOK))->hasSize(0);
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::BLOG))->hasSize(0);
+
+ //create one new social network
+ $post = [
+ 'social_new_type_1' => \Galette\Entity\Social::FACEBOOK,
+ 'social_new_value_1' => 'Galette does not have facebook',
+ ];
+
+ //existing social networks, change jabber ID
+ foreach ($socials as $social) {
+ $post['social_' . $social->id] = $social->url . ($social->type == \Galette\Entity\Social::JABBER ? ' - modified' : '');
+ }
+
+ $post = array_merge($preferences, $post);
+
+ $this->boolean($this->preferences->check($post, $this->login))->isTrue(print_r($this->preferences->getErrors(), true));
+ $this->boolean($this->preferences->store())->isTrue();
+
+ $socials = \Galette\Entity\Social::getListForMember(null);
+ $this->array($socials)->hasSize(3);
+
+ $search = \Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::MASTODON);
+ $this->array($search)->hasSize(1);
+ $masto = array_pop($search);
+ $this->string($masto->url)->isIdenticalTo('Galette mastodon URL');
+
+ $search = \Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::JABBER);
+ $this->array($search)->hasSize(1);
+ $jabber = array_pop($search);
+ $this->string($jabber->url)->isIdenticalTo('Galette jabber ID - modified');
+
+ $search = \Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::FACEBOOK);
+ $this->array($search)->hasSize(1);
+ $facebook = array_pop($search);
+ $this->string($facebook->url)->isIdenticalTo('Galette does not have facebook');
+
+ $post = [];
+
+ //existing social networks, drop mastodon
+ foreach ($socials as $social) {
+ if ($social->type != \Galette\Entity\Social::MASTODON) {
+ $post['social_' . $social->id] = $social->url;
+ }
+ }
+
+ $post = array_merge($preferences, $post);
+ $this->boolean($this->preferences->check($post, $this->login))->isTrue(print_r($this->preferences->getErrors(), true));
+ $this->boolean($this->preferences->store())->isTrue();
+
+ $socials = \Galette\Entity\Social::getListForMember(null);
+ $this->array($socials)->hasSize(2);
+
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::MASTODON))->hasSize(0);
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::JABBER))->hasSize(1);
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::FACEBOOK))->hasSize(1);
+ }
+
+ /**
+ * Test email signature
+ *
+ * @return void
+ */
+ public function testGetMailSignature()
+ {
+ $this->string($this->preferences->getMailSignature())->isIdenticalTo("\r\n-- \r\nGalette\r\n\r\n");
+
+ $this->preferences->pref_website = 'https://galette.eu';
+ $this->string($this->preferences->getMailSignature())->isIdenticalTo("\r\n-- \r\nGalette\r\n\r\nhttps://galette.eu");
+
+ //with legacy values
+ $this->preferences->pref_mailsign = "NAME}\r\n\r\n{WEBSITE}\r\n{GOOGLEPLUS}\r\n{FACEBOOK}\r\n{TWITTER}\r\n{LINKEDIN}\r\n{VIADEO}";
+ $this->string($this->preferences->getMailSignature())->isIdenticalTo("\r\n-- \r\nGalette\r\n\r\nhttps://galette.eu");
+
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->boolean(
+ $social
+ ->setType(\Galette\Entity\Social::MASTODON)
+ ->setUrl('https://framapiaf.org/@galette')
+ ->setLinkedMember(null)
+ ->store()
+ )->isTrue();
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::MASTODON))->hasSize(1);
+
+ $this->preferences->pref_mail_sign = "{ASSO_NAME}\r\n\r\n{ASSO_WEBSITE} - {ASSO_SOCIAL_MASTODON}";
+ $this->string($this->preferences->getMailSignature())->isIdenticalTo("\r\n-- \r\nGalette\r\n\r\nhttps://galette.eu - https://framapiaf.org/@galette");
+
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->boolean(
+ $social
+ ->setType(\Galette\Entity\Social::MASTODON)
+ ->setUrl('Galette mastodon URL - the return')
+ ->setLinkedMember(null)
+ ->store()
+ )->isTrue();
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::MASTODON))->hasSize(2);
+ $this->string($this->preferences->getMailSignature())->isIdenticalTo("\r\n-- \r\nGalette\r\n\r\nhttps://galette.eu - https://framapiaf.org/@galette, Galette mastodon URL - the return");
+ }
+
+ /**
+ * Test getLegend
+ *
+ * @return void
+ */
+ public function testGetLegend()
+ {
+ $legend = $this->preferences->getLegend();
+ $this->array($legend)->hasSize(2);
+ $this->array($legend['main']['patterns'])->hasSize(8);
+ $this->array($legend['socials']['patterns'])->hasSize(9);
+ $this->array($legend['socials']['patterns']['asso_social_mastodon'])->isIdenticalTo([
+ 'title' => __('Mastodon'),
+ 'pattern' => '/{ASSO_SOCIAL_MASTODON}/'
+ ]);
+
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->boolean(
+ $social
+ ->setType('mynewtype')
+ ->setUrl('Galette specific social network URL')
+ ->setLinkedMember(null)
+ ->store()
+ )->isTrue();
+
+ $legend = $this->preferences->getLegend();
+ $this->array($legend)->hasSize(2);
+ $this->array($legend['socials']['patterns'])->hasSIze(10)->hasKey('asso_social_mynewtype');
+ $this->array($legend['socials']['patterns']['asso_social_mynewtype'])->isIdenticalTo([
+ 'title' => 'mynewtype',
+ 'pattern' => '/{ASSO_SOCIAL_MYNEWTYPE}/'
+ ]);
+ }
}
'dues' => true,
'parent' => false,
'children' => false,
- 'dynamics' => false
+ 'dynamics' => false,
+ 'socials' => false
];
$this->adh = new \Galette\Entity\Adherent($this->zdb);
'dues' => false,
'parent' => false,
'children' => false,
- 'dynamics' => false
+ 'dynamics' => false,
+ 'socials' => false
];
$this->array($adh->deps)->isIdenticalTo($expected);
'dues' => true,
'parent' => false,
'children' => true,
- 'dynamics' => true
+ 'dynamics' => true,
+ 'socials' => false
];
$adh
->enableDep('dues')
'dues' => true,
'parent' => false,
'children' => false,
- 'dynamics' => true
+ 'dynamics' => true,
+ 'socials' => false
];
$adh->disableDep('children');
$this->array($adh->deps)->isIdenticalTo($expected);
'dues' => true,
'parent' => true,
'children' => true,
- 'dynamics' => true
+ 'dynamics' => true,
+ 'socials' => true
];
$adh->enableAllDeps('children');
$this->array($adh->deps)->isIdenticalTo($expected);
'dues' => false,
'parent' => false,
'children' => false,
- 'dynamics' => false
+ 'dynamics' => false,
+ 'socials' => false
];
$adh = new \Galette\Entity\Adherent(
$this->zdb,
$check = $adh->check($data, [], []);
$this->array($check)->isIdenticalTo($expected);
- $data = [
- 'email_adh' => '',
- 'url_adh' => 'mywebsite'
- ];
- $expected = ['- Non-valid Website address! Maybe you\'ve skipped the http://?'];
- $check = $adh->check($data, [], []);
- $this->array($check)->isIdenticalTo($expected);
-
- $data = ['url_adh' => 'http://'];
- $expected = ['- Non-valid Website address! Maybe you\'ve skipped the http://?'];
- $check = $adh->check($data, [], []);
- $this->boolean($check)->isTrue($expected);
- $this->variable($adh->_website)->isIdenticalTo('');
-
$data = ['login_adh' => 'a'];
$expected = ['- The username must be composed of at least 2 characters!'];
$check = $adh->check($data, [], []);
*
* PHP version 5
*
- * Copyright © 2013-2014 The Galette Team
+ * Copyright © 2016-2021 The Galette Team
*
* This file is part of Galette (http://galette.tuxfamily.org).
*
* @package GaletteTests
*
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2016 The Galette Team
+ * @copyright 2016-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @version SVN: $Id$
* @link http://galette.tuxfamily.org
* @name FieldsConfig
* @package GaletteTests
* @author Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2016 The Galette Team
+ * @copyright 2016-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since 2016-09-24
$this->array($categorized[\Galette\Entity\FieldsCategories::ADH_CATEGORY_GALETTE])
->hasSize(11);
$this->array($categorized[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT])
- ->hasSize(15);
+ ->hasSize(11);
}
/**
$town['required'] = false;
$town['visible'] = \Galette\Entity\FieldsConfig::NOBODY;
- //jabber
- $jabber = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][10];
- $jabber['position'] = count($fields[1]);
- unset($fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][10]);
- $jabber['category'] = \Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY;
- $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][] = $jabber;
+ //gsm
+ $gsm = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][6];
+ $gsm['position'] = count($fields[1]);
+ unset($fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][6]);
+ $gsm['category'] = \Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY;
+ $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][] = $gsm;
$this->boolean($fields_config->setFields($fields))->isTrue();
$this->boolean($town['required'])->isFalse();
$this->integer($town['visible'])->isIdenticalTo(\Galette\Entity\FieldsConfig::NOBODY);
- $jabber2 = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][12];
- $this->array($jabber2)->isIdenticalTo($jabber);
+ $gsm2 = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][12];
+ $this->array($gsm2)->isIdenticalTo($gsm);
}
/**
$this->object($elements[1])->isInstanceOf('\stdClass');
$this->integer($elements[1]->id)->isIdenticalTo(3);
- $this->array($elements[1]->elements)->hasSize(10);
+ $this->array($elements[1]->elements)->hasSize(8);
$this->object($elements[2])->isInstanceOf('\stdClass');
$this->integer($elements[2]->id)->isIdenticalTo(2);
$this->object($elements[1])->isInstanceOf('\stdClass');
$this->integer($elements[1]->id)->isIdenticalTo(3);
- $this->array($elements[1]->elements)->hasSize(10);
+ $this->array($elements[1]->elements)->hasSize(8);
$this->object($elements[2])->isInstanceOf('\stdClass');
$this->integer($elements[2]->id)->isIdenticalTo(2);
$this->object($elements['fieldsets'][1])->isInstanceOf('\stdClass');
$this->integer($elements['fieldsets'][1]->id)->isIdenticalTo(3);
- $this->array($elements['fieldsets'][1]->elements)->hasSize(11);
+ $this->array($elements['fieldsets'][1]->elements)->hasSize(9);
$this->object($elements['fieldsets'][2])->isInstanceOf('\stdClass');
$this->integer($elements['fieldsets'][2]->id)->isIdenticalTo(2);
$this->object($elements['fieldsets'][1])->isInstanceOf('\stdClass');
$this->integer($elements['fieldsets'][1]->id)->isIdenticalTo(3);
- $this->array($elements['fieldsets'][1]->elements)->hasSize(11);
+ $this->array($elements['fieldsets'][1]->elements)->hasSize(9);
$mail = $elements['fieldsets'][1]->elements['email_adh'];
$this->boolean($mail->required)->isFalse(); //email is not required per default
$this->object($elements['fieldsets'][1])->isInstanceOf('\stdClass');
$this->integer($elements['fieldsets'][1]->id)->isIdenticalTo(3);
- $this->array($elements['fieldsets'][1]->elements)->hasSize(11);
+ $this->array($elements['fieldsets'][1]->elements)->hasSize(9);
$mail = $elements['fieldsets'][1]->elements['email_adh'];
$this->boolean($mail->required)->isTrue(); //email is required for self subscription
$town['required'] = false;
$town['visible'] = \Galette\Entity\FieldsConfig::NOBODY;
- //jabber
- $jabber = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][10];
- $jabber['position'] = count($fields[1]);
- unset($fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][10]);
- $jabber['category'] = \Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY;
- $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][] = $jabber;
+ //gsm
+ $gsm = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][5]; //6 in FieldsConfig but 5 here.
+ $gsm['position'] = count($fields[1]);
+ unset($fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_CONTACT][5]); //6 in FieldsConfig but 5 here.
+ $gsm['category'] = \Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY;
+ $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][] = $gsm;
$this->boolean($lists_config->setFields($fields))->isTrue();
$this->boolean($town['required'])->isFalse();
$this->integer($town['visible'])->isIdenticalTo(\Galette\Entity\FieldsConfig::NOBODY);
- $jabber2 = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][10]; //12 in FieldsConfig but 10 here
- $this->array($jabber2)->isIdenticalTo($jabber);
- // /copied from FieldsConfig::testSetFields to ensure it works as excpeted from here.
+ $gsm2 = $fields[\Galette\Entity\FieldsCategories::ADH_CATEGORY_IDENTITY][10]; //12 in FieldsConfig but 10 here
+ $this->array($gsm2)->isIdenticalTo($gsm);
+ // /copied from FieldsConfig::testSetFields to ensure it works as expected from here.
}
/**
'pseudo_adh' => 'ubertrand',
'pays_adh' => 'Antarctique',
'tel_adh' => '0439153432',
- 'url_adh' => 'http://bouchet.com/',
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-06-10',
--- /dev/null
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Socials tests
+ *
+ * PHP version 5
+ *
+ * Copyright © 2021 The Galette Team
+ *
+ * This file is part of Galette (http://galette.tuxfamily.org).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Entity
+ * @package GaletteTests
+ *
+ * @author Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2019 The Galette Team
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @version SVN: $Id$
+ * @link http://galette.tuxfamily.org
+ * @since 2021-10-26
+ */
+
+namespace Galette\Entity\test\units;
+
+use Galette\GaletteTestCase;
+
+/**
+ * Status tests
+ *
+ * @category Entity
+ * @name Social
+ * @package GaletteTests
+ * @author Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2021 The Galette Team
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link http://galette.tuxfamily.org
+ * @since 2021-10-26
+ */
+class Social extends GaletteTestCase
+{
+ protected $seed = '25568744158';
+
+ /**
+ * Tear down tests
+ *
+ * @param string $method Calling method
+ *
+ * @return void
+ */
+ public function afterTestMethod($method)
+ {
+ parent::afterTestMethod($method);
+
+ $this->deleteSocials();
+
+ //drop dynamic translations
+ $delete = $this->zdb->delete(\Galette\Core\L10n::TABLE);
+ $this->zdb->execute($delete);
+
+ $delete = $this->zdb->delete(\Galette\Entity\Adherent::TABLE);
+ $delete->where(['fingerprint' => 'FAKER' . $this->seed]);
+ $this->zdb->execute($delete);
+
+ $this->cleanHistory();
+ }
+
+ /**
+ * Delete socials
+ *
+ * @return void
+ */
+ private function deleteSocials()
+ {
+ $delete = $this->zdb->delete(\Galette\Entity\Social::TABLE);
+ $this->zdb->execute($delete);
+ }
+
+ /**
+ * Test social object
+ *
+ * @return void
+ */
+ public function testObject()
+ {
+ $social = new \Galette\Entity\Social($this->zdb);
+
+ //setters and getters
+ $this->object($social->setType('mytype'))->isInstanceOf('\Galette\Entity\Social');
+ $this->string($social->type)->isIdenticalTo('mytype');
+
+ $this->object($social->setUrl('myurl'))->isInstanceOf('\Galette\Entity\Social');
+ $this->string($social->url)->isIdenticalTo('myurl');
+
+ //null as member id for Galette main preferences
+ $this->object($social->setLinkedMember(null))->isInstanceOf('\Galette\Entity\Social');
+ $this->variable($social->id_adh)->isNull();
+ $this->variable($social->member)->isNull();
+
+ $this->getMemberTwo();
+ $this->object($social->setLinkedMember($this->adh->id))->isInstanceOf(\Galette\Entity\Social::class);
+ $this->integer($social->id_adh)->isIdenticalTo($this->adh->id);
+ $this->object($social->member)->isInstanceOf(\Galette\Entity\Adherent::class);
+ $this->string($social->member->name)->isIdenticalTo($this->adh->name);
+ }
+
+ /**
+ * Test socials "system" types
+ *
+ * @return void
+ */
+ public function testGetSystemTypes()
+ {
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->array($social->getSystemTypes())->hasSize(9);
+ $this->array($social->getSystemTypes())->isIdenticalTo($social->getSystemTypes(true));
+ $this->array($social->getSystemTypes(false))->hasSize(9);
+
+ $this->string($social->getSystemType(\Galette\Entity\Social::TWITTER))->isIdenticalTo('Twitter');
+ $this->string($social->getSystemType(\Galette\Entity\Social::TWITTER, false))->isIdenticalTo('twitter');
+ }
+
+ /**
+ * Test getListForMember
+ *
+ * @return void
+ */
+ public function testGetListForMember(): void
+ {
+ $this->array(\Galette\Entity\Social::getListForMember(null))->isEmpty();
+
+ $this->getMemberTwo();
+ $this->array(\Galette\Entity\Social::getListForMember($this->adh->id))->isEmpty();
+
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->boolean(
+ $social
+ ->setType(\Galette\Entity\Social::MASTODON)
+ ->setUrl('mastodon URL')
+ ->setLinkedMember($this->adh->id)
+ ->store()
+ )->isTrue();
+
+ $socials = \Galette\Entity\Social::getListForMember($this->adh->id);
+ $this->array($socials)->HasSize(1);
+ $social = array_pop($socials);
+ $this->string($social->type)->isIdenticalTo(\Galette\Entity\Social::MASTODON);
+ $this->integer($social->id_adh)->isIdenticalTo($this->adh->id);
+ $this->string($social->url)->isIdenticalTo('mastodon URL');
+
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->boolean(
+ $social
+ ->setType(\Galette\Entity\Social::MASTODON)
+ ->setUrl('Galette mastodon URL')
+ ->setLinkedMember(null)
+ ->store()
+ )->isTrue();
+
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->boolean(
+ $social
+ ->setType(\Galette\Entity\Social::JABBER)
+ ->setUrl('Galette jabber')
+ ->setLinkedMember(null)
+ ->store()
+ )->isTrue();
+
+ $social = new \Galette\Entity\Social($this->zdb);
+ $this->boolean(
+ $social
+ ->setType(\Galette\Entity\Social::MASTODON)
+ ->setUrl('Another Galette mastodon URL')
+ ->setLinkedMember(null)
+ ->store()
+ )->isTrue();
+
+ $this->array(\Galette\Entity\Social::getListForMember(null))->hasSize(3);
+ $this->array(\Galette\Entity\Social::getListForMember(null, \Galette\Entity\Social::JABBER))->hasSize(1);
+
+ $this->boolean($social->remove())->isTrue();
+ $this->array(\Galette\Entity\Social::getListForMember(null))->hasSize(2);
+ }
+}
'pseudo_adh' => 'tgonzalez',
'pays_adh' => null,
'tel_adh' => '+33 8 93 53 99 52',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-03-09',
'pseudo_adh' => 'agnes.evrard',
'pays_adh' => null,
'tel_adh' => '0288284193',
- 'url_adh' => 'https://leroux.fr/omnis-autem-suscipit-consequuntur-possimus-sint-iste-beatae.html',
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2019-11-29',
'pseudo_adh' => 'fgay',
'pays_adh' => null,
'tel_adh' => '+33 7 45 45 19 81',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 8,
'date_crea_adh' => '2019-02-03',
'pseudo_adh' => 'chauvin.guillaume',
'pays_adh' => 'Hong Kong',
'tel_adh' => '+33 5 48 57 32 28',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 1,
'date_crea_adh' => '2017-11-20',
'pseudo_adh' => 'sauvage.dorothee',
'pays_adh' => 'Bangladesh',
'tel_adh' => '+33 4 75 14 66 56',
- 'url_adh' => null,
'activite_adh' => false,
'id_statut' => 9,
'date_crea_adh' => '2018-08-16',
'pseudo_adh' => 'andre.guillou',
'pays_adh' => null,
'tel_adh' => '09 26 70 06 55',
- 'url_adh' => 'http://www.hoarau.fr/quis-neque-ducimus-quidem-et',
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2018-09-28',
'pseudo_adh' => 'ferreira.rene',
'pays_adh' => 'Tuvalu',
'tel_adh' => '+33 (0)7 47 56 89 70',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2018-01-13',
'pseudo_adh' => 'roger27',
'pays_adh' => 'Antilles néerlandaises',
'tel_adh' => '0922523762',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-02-13',
'pseudo_adh' => 'julien.isabelle',
'pays_adh' => 'Mexique',
'tel_adh' => '0809527977',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2019-06-26',
'pseudo_adh' => 'louis.pruvost',
'pays_adh' => null,
'tel_adh' => '+33 (0)6 80 24 46 58',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-08-09',
'pseudo_adh' => 'olivier.roux',
'pays_adh' => 'République Dominicaine',
'tel_adh' => '08 95 04 73 14',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-07-31',
'pseudo_adh' => 'hchevalier',
'pays_adh' => 'Kiribati',
'tel_adh' => '04 55 49 80 92',
- 'url_adh' => 'http://www.leblanc.com/nemo-non-rerum-commodi-sequi-ut',
'activite_adh' => true,
'id_statut' => 1,
'date_crea_adh' => '2020-06-02',
'pseudo_adh' => 'abarre',
'pays_adh' => 'Kirghizistan',
'tel_adh' => '07 47 63 11 31',
- 'url_adh' => 'https://www.jacques.com/fuga-voluptatem-tenetur-rem-possimus',
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-10-28',
'pseudo_adh' => 'frederique.bernier',
'pays_adh' => null,
'tel_adh' => '+33 2 50 03 01 12',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-08-14',
'pseudo_adh' => 'stoussaint',
'pays_adh' => 'Îles Mineures Éloignées des États-Unis',
'tel_adh' => '+33 (0)1 30 50 01 54',
- 'url_adh' => 'http://www.lemaitre.org/dolorum-recusandae-non-eum-non',
'activite_adh' => true,
'id_statut' => 3,
'date_crea_adh' => '2018-12-05',
'pseudo_adh' => 'virginie.jacquet',
'pays_adh' => null,
'tel_adh' => '0393209420',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2018-02-17',
'pseudo_adh' => 'diallo.sebastien',
'pays_adh' => null,
'tel_adh' => '+33 5 72 28 24 81',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-03-16',
'pseudo_adh' => 'helene59',
'pays_adh' => null,
'tel_adh' => '0383453389',
- 'url_adh' => 'http://www.lesage.com/et-aperiam-labore-est-libero-voluptatem.html',
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-02-03',
'pseudo_adh' => 'wpierre',
'pays_adh' => null,
'tel_adh' => '01 32 14 47 74',
- 'url_adh' => null,
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-03-28',
'pseudo_adh' => 'gerard66',
'pays_adh' => null,
'tel_adh' => '+33 1 46 04 81 87',
- 'url_adh' => 'http://www.thierry.com/',
'activite_adh' => true,
'id_statut' => 5,
'date_crea_adh' => '2019-05-16',
'pseudo_adh' => 'ubertrand',
'pays_adh' => 'Antarctique',
'tel_adh' => '0439153432',
- 'url_adh' => 'http://bouchet.com/',
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2020-06-10',
'pseudo_adh' => 'vallet.camille',
'pays_adh' => null,
'tel_adh' => '05 59 53 59 43',
- 'url_adh' => 'http://bodin.net/omnis-ratione-sint-dolorem-architecto',
'activite_adh' => true,
'id_statut' => 9,
'date_crea_adh' => '2019-05-20',
'cp_adh' => '39 069',
'pays_adh' => 'Antarctique',
'tel_adh' => '0439153432',
- 'url_adh' => 'http://bouchet.com/',
'activite_adh' => true,
'id_statut' => 9,
'pref_lang' => 'en_US',
'pseudo_adh' => 'vallet.camille',
'pays_adh' => '',
'tel_adh' => '05 59 53 59 43',
- 'url_adh' => 'http://bodin.net/omnis-ratione-sint-dolorem-architecto',
'activite_adh' => true,
'id_statut' => 9,
'pref_lang' => 'ca',
"pseudo_adh": "marcetienne25",
"pays_adh": null,
"tel_adh": "+33 2 93 73 14 36",
- "url_adh": "http:\/\/www.perrin.net\/",
"activite_adh": true,
"id_statut": 9,
"date_crea_adh": "2017-08-07",
"pays_adh": "Bangladesh",
"societe_adh": "Galette, Inc.",
"tel_adh": "+33 (0)5 41 65 71 46",
- "url_adh": "http:\/\/coulon.fr\/eos-nesciunt-consectetur-dolores-omnis-provident-explicabo",
"activite_adh": true,
"id_statut": 1,
"date_crea_adh": "2017-08-07",
"pseudo_adh": "nleclerc",
"pays_adh": null,
"tel_adh": "0895352968",
- "url_adh": null,
"activite_adh": true,
"id_statut": 9,
"date_crea_adh": "2017-08-07",
"pseudo_adh": "benjamin.germain",
"pays_adh": "Autriche",
"tel_adh": "+33 5 56 55 02 16",
- "url_adh": "http:\/\/www.bourgeois.fr\/accusamus-sapiente-est-quia-facilis-quas-exercitationem.html",
"activite_adh": true,
"id_statut": 5,
"date_crea_adh": "2017-08-07",
"pseudo_adh": "martine56",
"pays_adh": "Autriche",
"tel_adh": "+33 5 56 55 02 16",
- "url_adh": "http:\/\/www.bourgeois.fr\/accusamus-sapiente-est-quia-facilis-quas-exercitationem.html",
"activite_adh": true,
"id_statut": 5,
"date_crea_adh": "2017-08-07",
"pseudo_adh": "laetitia.sanchez",
"pays_adh": "Norv\u00e8ge",
"tel_adh": "0129447169",
- "url_adh": null,
"activite_adh": true,
"id_statut": 9,
"date_crea_adh": "2017-08-07",
"pseudo_adh": "elodie.bigot",
"pays_adh": "Montserrat",
"tel_adh": "+33 6 87 22 98 19",
- "url_adh": null,
"activite_adh": false,
"id_statut": 4,
"date_crea_adh": "2017-08-07",
"pseudo_adh": "victoire64",
"pays_adh": null,
"tel_adh": "03 43 89 01 97",
- "url_adh": null,
"activite_adh": true,
"id_statut": 9,
"date_crea_adh": "2017-08-07",
"pays_adh": "Ouzb\u00e9kistan",
"societe_adh": "Galette, Inc.",
"tel_adh": "+33 (0)8 06 28 91 89",
- "url_adh": "http:\/\/paris.net\/",
"activite_adh": true,
"id_statut": 9,
"date_crea_adh": "2017-08-07",
"pseudo_adh": "dramos",
"pays_adh": "Danemark",
"tel_adh": "+33 (0)1 03 04 16 21",
- "url_adh": "http:\/\/www.lopes.com\/",
"activite_adh": true,
"id_statut": 6,
"date_crea_adh": "2017-08-07",