Skip to content

Commit

Permalink
Merge pull request #361 from pantheon-systems/sites_cache_redo
Browse files Browse the repository at this point in the history
Include memberships data in SitesCache and use to fill `sites list`
  • Loading branch information
bensheldon committed Aug 10, 2015
2 parents 4d33a38 + 60db0c4 commit b94f8eb
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 188 deletions.
14 changes: 10 additions & 4 deletions php/FileCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,17 @@ public function read( $key, $ttl = null ) {
}
}

public function get_data( $key, $ttl = null ) {
$contents = $this->read( $key, $ttl );
public function get_data($key, $options = array()) {
$defaults = array(
'decode_array' => false,
'ttl' => null
);
$options = array_merge($defaults, $options);

if ( $contents ) {
return json_decode( $contents );
$contents = $this->read($key, $options['ttl']);

if ($contents) {
return json_decode($contents, $options['decode_array']);
}
else {
return false;
Expand Down
24 changes: 11 additions & 13 deletions php/Terminus/Helpers/Input.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use \Terminus\User;
use \Terminus\SiteFactory;
use \Terminus\SitesCache;
use \Terminus\Products;

/**
Expand Down Expand Up @@ -195,22 +196,19 @@ public static function orgname($args, $key) {
* @param [string] $label Prompt for STDOUT
* @return [string] Site name
*/
public static function site(
$args = array(),
$key = 'site',
$label = 'Choose site'
) {
// early return if a valid site has been offered
public static function sitename($args = array(), $key = 'site', $label = 'Choose site') {
// return early if sitename is provided in args
if(isset($args[$key])) {
if($site = SiteFactory::instance($args[$key])) {
$site_name = $site->getName();
return $site_name;
}
return $args[$key];
}
$sites = SiteFactory::instance();
$sitesCache = new SitesCache();
$sitenames = array_map(function($site_cache) {
return $site_cache['name'];
}, $sitesCache->all());

$choices = array();
foreach($sites as $site) {
$choices[$site->information->name] = $site->information->name;
foreach($sitenames as $sitename) {
$choices[$sitename] = $sitename;
}
$menu = self::menu($choices, $default = null, $label);
return $menu;
Expand Down
188 changes: 149 additions & 39 deletions php/Terminus/SitesCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,105 +7,215 @@
use \Terminus_Command;
use Terminus\Session;

use Psy;

/**
* Persists a mapping between Site names and Site IDs
* This is stored in the filecache in a json schema like so:
*
* {
* "<site_name>" : {
* id: "<site_uuid>",
* name: "<site_name>",
* framework: "<framework>",
* service_level: "<service_level>"
* memberships: {
* "<membership_id>": {
* id: "<membership_id",
* name: "<Team|Organization Name>"
* type: "<team|organization>",
* },...
* }
* },...
* }
*
*/
class SitesCache {
protected $cache;
protected $cachekey = 'sites';

/**
* Searches the SitesCache for an ID given a name
*
*/
static function find($name, $options = array()) {
$instance = new SitesCache();
return $instance->_find($name, $options);
}

public function __construct() {
$this->cache = Terminus::get_cache();
}

private function _find($name, $options = array()) {
if (!isset($options['rebuild'])) {
$options['rebuild'] = true;
}
private function find($name, $options = array()) {
$defaults = array('rebuild' => true);
$options = array_merge($defaults, $options);

if (isset($this->all()[$name])) {
return $this->all()[$name];
$site_data = $this->all()[$name];
return $site_data;
} else {
if ($options['rebuild']) {
$this->rebuild();
return $this->find($name, array('rebuild' => false));
$recurse_without_rebuild = $this->find($name, array('rebuild' => false));
return $recurse_without_rebuild;
} else {
return false;
return null;
}
}
}

/**
* Searches the SitesCache for an ID given a name
*
*/
public function findID($name, $options = array()) {
$site_data = $this->find($name, $options);
if ($site_data) {
$site_id = $site_data['id'];
return $site_id;
} else {
return null;
}
}

public function all() {
return (array) $this->cache->get_data($this->cachekey);
$cache_data = $this->cache->get_data($this->cachekey, array('decode_array' => true));
if ($cache_data) {
return $cache_data;
} else {
return array();
}
}

public function add($list = array()) {
$data = array_merge(
(array) $this->cache->get_data($this->cachekey),
$list
);
$this->cache->put_data($this->cachekey, $data);
/**
* Adds a record for a site to the cache. Records should either be a single assoc_aray
* or a list of arrays that look like this:
*
* array(
* "id" => "<site_id>"
* "name" => "<site_name>"
* "membership" => array(
* 'id' => "<user_id|org_id>"
* 'name' => "<Team|org_name>"
* 'type' => "<team|organization>"
* )
* )
*/
public function add($memberships_data = array()) {
$cache = (array) $this->cache->get_data($this->cachekey, array('decode_array' => true));

// if a single site item is passed in, wrap it in an array
if (isset($memberships_data['id'])) {
$memberships_data = array($memberships_data);
}

foreach ($memberships_data as $membership_data) {
$site_id = $membership_data['id'];
$site_name = $membership_data['name'];
$site_framework = $membership_data['framework'];
$site_service_level = $membership_data['service_level'];
$membership = $membership_data['membership'];
$membership_id = $membership_data['membership']['id'];

if (!isset($cache[$site_name]) || !isset($cache[$site_name]['memberships'])) {
// if site is not in cache, add a new entry
$cache[$site_name] = array(
'id' => $site_id,
'name' => $site_name,
'framework' => $site_framework,
'service_level' => $site_service_level,
'memberships' => array()
);
}

// then add the membership
$cache[$site_name]['memberships'][$membership_id] = $membership;
}

# and save the cache
$this->cache->put_data($this->cachekey, $cache);

return $this->all();
}

public function rebuild() {
// Clear out the cache
$this->cache->put_data($this->cachekey, array());

// Add user's own sites
$this->add($this->fetch_user_sites());

// Add all sites for each of user's organizations
$org_ids = array_keys($this->fetch_user_organizations());
foreach ($org_ids as $org_id) {
$this->add($this->fetch_organization_sites($org_id));
$orgs_data = $this->fetch_user_organizations();

foreach ($orgs_data as $org_data) {
$this->add($this->fetch_organization_sites($org_data));
}

return $this->all();
}

public function remove($sitename) {
$cache = (array) $this->cache->get_data($this->cachekey, array('decode_array' => true));
unset($cache[$sitename]);
$this->cache->put_data($this->cachekey, $cache);
}

public function clear() {
$this->cache->put_data($this->cachekey, array());
}

public function fetch_user_sites() {
$response = Terminus_Command::paged_request('users/' . Session::getValue('user_uuid') . '/memberships/sites');
$user_id = Session::getValue('user_uuid');
$response = Terminus_Command::paged_request('users/' . $user_id . '/memberships/sites');

$data = array();
$memberships_data = array();
foreach ($response['data'] as $membership) {
$data[$membership->site->name] = $membership->id;
$memberships_data[] = array(
'id' => $membership->id,
'name' => $membership->site->name,
'framework' => $membership->site->framework,
'service_level' => $membership->site->service_level,
'membership' => array(
'id' => $user_id,
'name' => 'Team',
'type' => 'team',
)
);
}

return $data;
return $memberships_data;
}

public function fetch_user_organizations() {
$response = Terminus_Command::paged_request('users/' . Session::getValue('user_uuid') . '/memberships/organizations');

$data = array();
foreach ($response['data'] as $membership) {
if ($membership->role != 'unprivileged') {
$data[$membership->id] = $membership->organization->profile->name;
if ($membership->role == 'unprivileged') {
// Users with unprivileged role in organizations can't see organization sites
// but must be added to the team
continue;
}

$data[] = array(
'id' => $membership->id,
'name' => $membership->organization->profile->name,
'type' => 'organization'
);
}

return $data;
}

public function fetch_organization_sites($organization_id) {
$response = Terminus_Command::paged_request('organizations/' . $organization_id . '/memberships/sites');
public function fetch_organization_sites($org_data) {
$response = Terminus_Command::paged_request('organizations/' . $org_data['id'] . '/memberships/sites');

$data = array();
$memberships_data = array();
foreach ($response['data'] as $membership) {
$data[$membership->site->name] = $membership->id;
$memberships_data[] = array(
'id' => $membership->site->id,
'name' => $membership->site->name,
'framework' => $membership->site->framework,
'service_level' => $membership->site->service_level,
'membership' => array(
'id' => $org_data['id'],
'name' => $org_data['name'],
'type' => 'organization',
)
);
}

return $data;
return $memberships_data;
}
}
6 changes: 5 additions & 1 deletion php/commands/cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
*
*/
class CLI_Command extends Terminus_Command {
public function __construct() {
parent::__construct();
$this->sitesCache = new SitesCache();
}

private function command_to_array( $command ) {
$dump = array(
Expand Down Expand Up @@ -155,7 +159,7 @@ public function console($args, $assoc_args) {
$user = new User;
if (isset($assoc_args['site'])) {
$sitename = $assoc_args['site'];
$site_id = SitesCache::find($sitename);
$site_id = $this->sitesCache->findID($sitename);
$site = new Site($site_id);
}

Expand Down
4 changes: 2 additions & 2 deletions php/commands/organizations.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ public function sites($args, $assoc_args) {
$org = new Organization($selected_org);

if (isset($assoc_args['add'])) {
$add = SiteFactory::instance(Input::site($assoc_args,'add'));
$add = SiteFactory::instance(Input::sitename($assoc_args,'add'));
Terminus::confirm("Are you sure you want to add %s to %s ?", $assoc_args, array($add->getName(), $org->name));
$org->addSite($add);
Terminus::success("Added site!");
return true;
}

if (isset($assoc_args['remove'])) {
$remove = SiteFactory::instance(Input::site($assoc_args,'remove'));
$remove = SiteFactory::instance(Input::sitename($assoc_args,'remove'));
Terminus::confirm("Are you sure you want to remove %s to %s ?", $assoc_args, array($remove->getName(), $org->name));
$org->removeSite($remove);
Terminus::success("Removed site!");
Expand Down
Loading

0 comments on commit b94f8eb

Please sign in to comment.