Edits TODOs and XXXs.
[platal.git] / include / profilefields.inc.php
index 80eb725..16b8e1e 100644 (file)
@@ -46,7 +46,8 @@ abstract class ProfileField
      * @param $pids An array of pids
      * @param $visibility The level of visibility fetched fields must have
      * @return a PlIterator yielding data suitable for a "new ProfileBlah($data)"
-     * XXX MUST be reimplemented for each kind of ProfileField
+     *
+     * MUST be reimplemented for each kind of ProfileField.
      */
     public static function fetchData(array $pids, ProfileVisibility $visibility)
     {
@@ -154,6 +155,15 @@ class Phone
         }
     }
 
+    /** Returns the unique ID of a phone
+     * This ID will allow to link it to an address, a user or a job
+     * The format is address_addressId_phoneId (where phoneId is the id
+     * of the phone in the list of those associated with the address)
+     */
+    public function uid() {
+        return $this->link_type . '_' . $this->link_id . '_' . $this->id;
+    }
+
     public function hasFlags($flags) {
         return $this->hasType($flags) && $this->hasLink($flags);
     }
@@ -250,8 +260,8 @@ class Job
     public $id;
 
     public $company = null;
-    private $phones = array();
-    private $address = null;
+    public $phones = array();
+    public $address = null;
 
     public $jobid;
 
@@ -272,6 +282,11 @@ class Job
             $this->$key = $val;
         }
         $this->company = CompanyList::get($this->jobid);
+        if (is_null($this->company)) {
+            require_once 'validations.inc.php';
+            $entreprise = ProfileValidate::get_typed_requests($this->pid, 'entreprise');
+            $this->company = new Company(array('name' =>  $entreprise[$this->id]->name));
+        }
     }
 
     public function phones()
@@ -287,13 +302,13 @@ class Job
     public function addPhone(Phone &$phone)
     {
         if ($phone->link_type == Phone::LINK_JOB && $phone->link_id == $this->id && $phone->pid == $this->pid) {
-            $this->phones[] = $phone;
+            $this->phones[$phone->uid()] = $phone;
         }
     }
 
     public function setAddress(Address $address)
     {
-        if ($address->link_id == Address::LINK_JOB && $address->link_id == $this->id && $address->pid == $this->pid) {
+        if ($address->link_type == Address::LINK_JOB && $address->link_id == $this->id && $address->pid == $this->pid) {
             $this->address = $address;
         }
     }
@@ -307,7 +322,8 @@ class Address
     const LINK_PROFILE = 'home';
 
     public $flags;
-    public $link_id;
+    public $id; // The ID of the address among those associated with its link
+    public $link_id; // The ID of the object to which the address is linked (profile, job, company)
     public $link_type;
 
     public $text;
@@ -335,10 +351,20 @@ class Address
         $this->flags = new PlFlagSet($this->flags);
     }
 
+    public function uid() {
+        $uid = $this->link_type . '_';
+        if ($this->link_type != self::LINK_COMPANY) {
+            $uid .= $this->pid . '_';
+        }
+        $uid .= $this->link_id . '_' . $this->id;
+    }
+
     public function addPhone(Phone &$phone)
     {
-        if ($phone->link_type == Phone::LINK_ADDRESS && $phone->link_id == $this->id && $phone->pid == $this->pid) {
-            $this->phones[$phone->id] = $phone;
+        if (
+            $phone->link_type == Phone::LINK_ADDRESS && $phone->link_id == $this->id &&
+            ($this->link_type == self::LINK_COMPANY || $phone->pid == $this->pid) ) {
+            $this->phones[$phone->uid()] = $phone;
         }
     }
 
@@ -508,16 +534,13 @@ class ProfileNetworking extends ProfileField
 
     public function get($flags, $limit = null)
     {
-        if (!$flags) {
-            $flags = Profile::NETWORKING_ALL;
-        }
         $nws = array();
         $nb = 0;
         foreach ($this->networks as $id => $nw) {
             if (($flags & Profile::NETWORKING_WEB) && $nw['network_type']->hasFlag('web') ||
                 ($flags & Profile::NETWORKING_IM) && $nw['network_type']->hasFlag('im') ||
                 ($flags & Profile::NETWORKING_SOCIAL) && $nw['network_type']->hasFlag('social') ||
-                ($flags & Profile::NETWORKING_ALL)) {
+                ($flags == Profile::NETWORKING_ALL)) {
                 $nws[$id] = $nw;
                 ++$nb;
                 if (isset($limit) && $nb >= $limit) {
@@ -633,6 +656,64 @@ class ProfileMentoringCountries extends ProfileField
  * 3) attach addresses to jobs and profiles
  */
 
+// {{{ Database schema (profile_address, profile_phones, profile_jobs)
+/** The database for this is very unclear, so here is a little schema :
+ * profile_job describes a Job, links to:
+ * - a Profile, through `pid`
+ * - a Company, through `jobid`
+ * The `id` field is the id of this job in the list of the jobs of its profile
+ *
+ * profile_addresses describes an Address, which
+ * related to either a Profile, a Job or a Company:
+ * - for a Profile:
+ *   - `type` is set to 'home'
+ *   - `pid` is set to the related profile pid
+ *   - `id` is the id of the address in the list of those related to that profile
+ *   - `jobid` is empty
+ *
+ * - for a Company:
+ *   - `type` is set to 'hq'
+ *   - `pid` is set to 0
+ *   - `jobid` is set to the id of the company
+ *   - `id` is set to 0 (only one address per Company)
+ *
+ * - for a Job:
+ *   - `type` is set to 'job'
+ *   - `pid` is set to the pid of the Profile of the related Job
+ *   - `jobid` is set to the Company of the job (this information is redundant
+ *              with that of the row of profile_job for the related job)
+ *   - `id` is the id of the job to which we refer (i.e `profile_job.id`)
+ *
+ * profile_phone describes a Phone, which can be related to an Address,
+ * a Job, a Profile or a Company:
+ * - for a Profile:
+ *   - `link_type` is set to 'user'
+ *   - `link_id` is set to 0
+ *   - `pid` is set to the id of the related Profile
+ *
+ * - for a Company:
+ *   - `link_type` is set to 'hq'
+ *   - `link_id` is set to the id of the related Company
+ *   - `pid` is set to 0
+ *
+ * - for an Address (this is only possible for a *personal* address)
+ *   - `link_type` is set to 'address'
+ *   - `link_id` is set to the related Address `id`
+ *   - `pid` is set to the related Address `pid`
+ *
+ * - for a Job:
+ *   - `link_type` is set to 'pro'
+ *   - `link_id` is set to the related Job `id` (not `jobid`)
+ *   - `pid` is set to the related Job `pid`
+ *
+ *
+ * The possible relations are as follow:
+ * An Address can be linked to a Company, a Profile, a Job
+ * A Job is linked to a Company and a Profile
+ * A Phone can be linked to a Company, a Profile, a Job, or a Profile-related Address
+ */
+// }}}
+
 // {{{ class ProfileAddresses                         [ Field ]
 class ProfileAddresses extends ProfileField
 {
@@ -676,7 +757,7 @@ class ProfileAddresses extends ProfileField
     public static function fetchData(array $pids, ProfileVisibility $visibility)
     {
         $data = XDB::iterator('SELECT  pa.id, pa.pid, pa.flags, pa.type AS link_type,
-                                       IF(pa.type = \'home\', pid, jobid) AS link_id,
+                                       IF(pa.type = \'home\', pid, IF(pa.type = \'job\', pa.id, jobid)) AS link_id,
                                        pa.text, pa.postalCode, pa.latitude, pa.longitude, pa.comment,
                                        gl.name AS locality, gas.name AS subAdministrativeArea,
                                        ga.name AS administrativeArea, gc.countryFR AS country
@@ -855,7 +936,6 @@ class CompanyList
             self::$companies[$row['id']] = $cp;
         }
 
-        // TODO: determine whether there can be phones attached to a hq's address
         // Add phones to hq
         if (count($newcompanies)) {
             $it = XDB::iterator('SELECT  search_tel AS search, display_tel AS display, comment, link_id, tel_type AS type, link_type, tel_id AS id