Ignore:
Timestamp:
Mar 24, 2014, 9:22:43 PM (10 years ago)
Author:
plg
Message:

merge r27925 from branch 2.6 to trunk

bug 3057: avoid warnings and SQL crash when encountering inconsistent
permissions + rewrite permissions consistancy check when setting albums
to private status.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin/include/functions.php

    r26972 r27926  
    706706    pwg_query($query);
    707707  }
     708 
    708709  // make a category private => all its child categories become private
    709710  if ($value == 'private')
    710711  {
    711712    $subcats = get_subcat_ids($categories);
     713   
    712714    $query = '
    713715UPDATE '.CATEGORIES_TABLE.'
     
    715717  WHERE id IN ('.implode(',', $subcats).')';
    716718    pwg_query($query);
     719
     720    // We have to keep permissions consistant: a sub-album can't be
     721    // permitted to a user or group if its parent album is not permitted to
     722    // the same user or group. Let's remove all permissions on sub-albums if
     723    // it is not consistant. Let's take the following example:
     724    //
     725    // A1        permitted to U1,G1
     726    // A1/A2     permitted to U1,U2,G1,G2
     727    // A1/A2/A3  permitted to U3,G1
     728    // A1/A2/A4  permitted to U2
     729    // A1/A5     permitted to U4
     730    // A6        permitted to U4
     731    // A6/A7     permitted to G1
     732    //
     733    // (we consider that it can be possible to start with inconsistant
     734    // permission, given that public albums can have hidden permissions,
     735    // revealed once the album returns to private status)
     736    //
     737    // The admin selects A2,A3,A4,A5,A6,A7 to become private (all but A1,
     738    // which is private, which can be true if we're moving A2 into A1). The
     739    // result must be:
     740    //
     741    // A2 permission removed to U2,G2
     742    // A3 permission removed to U3
     743    // A4 permission removed to U2
     744    // A5 permission removed to U2
     745    // A6 permission removed to U4
     746    // A7 no permission removed
     747    //
     748    // 1) we must extract "top albums": A2, A5 and A6
     749    // 2) for each top album, decide which album is the reference for permissions
     750    // 3) remove all inconsistant permissions from sub-albums of each top-album
     751
     752    // step 1, search top albums
     753    $all_categories = array();
     754    $top_categories = array();
     755    $parent_ids = array();
     756   
     757    $query = '
     758SELECT
     759    id,
     760    name,
     761    id_uppercat,
     762    uppercats,
     763    global_rank
     764  FROM '.CATEGORIES_TABLE.'
     765  WHERE id IN ('.implode(',', $categories).')
     766;';
     767    $result = pwg_query($query);
     768    while ($row = pwg_db_fetch_assoc($result))
     769    {
     770      $all_categories[] = $row;
     771    }
     772   
     773    usort($all_categories, 'global_rank_compare');
     774
     775    foreach ($all_categories as $cat)
     776    {
     777      $is_top = true;
     778     
     779      if (!empty($cat['id_uppercat']))
     780      {
     781        foreach (explode(',', $cat['uppercats']) as $id_uppercat)
     782        {
     783          if (isset($top_categories[$id_uppercat]))
     784          {
     785            $is_top = false;
     786            break;
     787          }
     788        }
     789      }
     790
     791      if ($is_top)
     792      {
     793        $top_categories[$cat['id']] = $cat;
     794
     795        if (!empty($cat['id_uppercat']))
     796        {
     797          $parent_ids[] = $cat['id_uppercat'];
     798        }
     799      }
     800    }
     801
     802    // step 2, search the reference album for permissions
     803    //
     804    // to find the reference of each top album, we will need the parent albums
     805    $parent_cats = array();
     806
     807    if (count($parent_ids) > 0)
     808    {
     809      $query = '
     810SELECT
     811    id,
     812    status
     813  FROM '.CATEGORIES_TABLE.'
     814  WHERE id IN ('.implode(',', $parent_ids).')
     815;';
     816      $result = pwg_query($query);
     817      while ($row = pwg_db_fetch_assoc($result))
     818      {
     819        $parent_cats[$row['id']] = $row;
     820      }
     821    }
     822
     823    $tables = array(
     824      USER_ACCESS_TABLE => 'user_id',
     825      GROUP_ACCESS_TABLE => 'group_id'
     826      );
     827
     828    foreach ($top_categories as $top_category)
     829    {
     830      // what is the "reference" for list of permissions? The parent album
     831      // if it is private, else the album itself
     832      $ref_cat_id = $top_category['id'];
     833
     834      if (!empty($top_category['id_uppercat'])
     835          and isset($parent_cats[ $top_category['id_uppercat'] ])
     836          and 'private' == $parent_cats[ $top_category['id_uppercat'] ]['status'])
     837      {
     838        $ref_cat_id = $top_category['id_uppercat'];
     839      }
     840
     841      $subcats = get_subcat_ids(array($top_category['id']));
     842
     843      foreach ($tables as $table => $field)
     844      {
     845        // what are the permissions user/group of the reference album
     846        $query = '
     847SELECT '.$field.'
     848  FROM '.$table.'
     849  WHERE cat_id = '.$ref_cat_id.'
     850;';
     851        $ref_access = array_from_query($query, $field);
     852
     853        if (count($ref_access) == 0)
     854        {
     855          $ref_access[] = -1;
     856        }
     857
     858        // step 3, remove the inconsistant permissions from sub-albums
     859        $query = '
     860DELETE
     861  FROM '.$table.'
     862  WHERE '.$field.' NOT IN ('.implode(',', $ref_access).')
     863    AND cat_id IN ('.implode(',', $subcats).')
     864;';
     865        pwg_query($query);
     866      }
     867    }
    717868  }
    718869}
     
    11461297  if ('private' == $parent_status)
    11471298  {
    1148     foreach ($categories as $cat_id => $category)
    1149     {
    1150       if ('public' == $category['status'])
    1151       {
    1152         set_cat_status(array($cat_id), 'private');
    1153       }
    1154      
    1155       $subcats = get_subcat_ids(array($cat_id));
    1156 
    1157       foreach ($tables as $table => $field)
    1158       {
    1159         $query = '
    1160 SELECT '.$field.'
    1161   FROM '.$table.'
    1162   WHERE cat_id = '.$cat_id.'
    1163 ;';
    1164         $category_access = array_from_query($query, $field);
    1165 
    1166         $query = '
    1167 SELECT '.$field.'
    1168   FROM '.$table.'
    1169   WHERE cat_id = '.$new_parent.'
    1170 ;';
    1171         $parent_access = array_from_query($query, $field);
    1172 
    1173         $to_delete = array_diff($category_access, $parent_access);
    1174 
    1175         if (count($to_delete) > 0)
    1176         {
    1177           $query = '
    1178 DELETE FROM '.$table.'
    1179   WHERE '.$field.' IN ('.implode(',', $to_delete).')
    1180     AND cat_id IN ('.implode(',', $subcats).')
    1181 ;';
    1182           pwg_query($query);
    1183         }
    1184       }
    1185     }
     1299    set_cat_status(array_keys($categories), 'private');
    11861300  }
    11871301
Note: See TracChangeset for help on using the changeset viewer.