/**
  * Determines if this property can be seen by the given $viewer.
  * If $viewer is the property's owner, or an administrator, returns true. Otherwise it will compare
  * this property's visible networks with the networks of the viewer, and if at least one matches,
  * this method will return true.
  *
  * @param User $viewer
  * @param array $viewerNetworkIds
  * @return bool
  */
 public function isVisibleBy(User $viewer = null, $viewerNetworkIds = null)
 {
     $visibility = $this->getVisibility();
     // if public, true right away. if not public and the viewer is a guest, false right away.
     if ($visibility == self::VISIBLE_PUBLIC) {
         return true;
     } else {
         if (!$viewer) {
             return false;
         }
     }
     // if we are viewing our own profile, true.
     if ($viewer && $viewer->getId() == $this->getUser()->getId()) {
         return true;
     }
     // if we are an admin, true.
     // however we name these... ROLE_ADMIN is part of symfony, Administrators may be a new thing.
     $viewerRoles = $viewer ? $viewer->getRoles() : [];
     if (in_array('ROLE_SUPER_ADMIN', $viewerRoles) || in_array('Administrator', $viewerRoles)) {
         return true;
     }
     // handle private (false except for owner/admin, handled above), and all registered users.
     if ($visibility == self::VISIBLE_PRIVATE) {
         return false;
     } else {
         if ($visibility == self::VISIBLE_MEMBERS) {
             return $viewer ? true : false;
         }
     }
     // handle custom network-based visibility.
     // if a list of the viewer's network ids is passed, use that to save on processing time.
     if ($viewerNetworkIds === null) {
         $viewerNetworkIds = [];
         foreach ($viewer->getNetworks() as $vnet) {
             $viewerNetworkIds[] = $vnet->getNetwork()->getId();
         }
     }
     return $this->hasIntersectingNetworks($viewerNetworkIds);
 }