blob: e8d608a14cf98def51f77e75030acfb069b74271 [file] [log] [blame]
<?php
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once("CasBrowser.class.php");
class Utils{
public static $acceptedReturnTypes = array('html', 'json');
/**
* @param types
* An array of PoductTypes.
*
* @return
* An array of unique names of Metadata and Elements associated with the given
* ProductTypes.
*/
public static function getMetadataElements($types){
$cb = new CasBrowser();
$client = $cb->getClient();
$metadataNames = array();
foreach($types as $type){
foreach(array_keys($type->getTypeMetadata()->toAssocArray()) as $metadata){
if(!in_array($metadata, $metadataNames)){
array_push($metadataNames, $metadata);
}
}
foreach($client->getElementsByProductType($type) as $element){
$elementName = $element->getElementName();
if(!in_array($elementName, $metadataNames)){
array_push($metadataNames, $elementName);
}
}
}
return $metadataNames;
}
/**
* @param productType
* The productType of the ProductPage desired.
*
* @param pageNum
* The number of the page desired in the set of ProductPages of that ProductType.
*
* @return
* The requested ProductPage object.
*/
public static function getPage($productType, $pageNum){
$cb = new CasBrowser();
$client = $cb->getClient();
// Iterate until the proper page is reached
for($page = $client->getFirstPage($productType);
$page->getPageNum() < $pageNum && $page->getPageNum() < $page->getTotalPages();
$page = $client->getNextPage($productType, $page)){}
return $page;
}
public static function getRequestedReturnType($requestedType){
$lowerRequestedType = strtolower($requestedType);
if(!in_array($lowerRequestedType, self::$acceptedReturnTypes)){
throw new CasBrowserException('Error: The requested return type of '. $requestedType . 'is not accepted.');
}
return $lowerRequestedType;
}
public static function getProductListMetadata($products){
$payload = array();
foreach($products as $p){
$cb = new CasBrowser();
$client = $cb->getClient();
$met = $client->getMetadata($p);
$payload[$p->getId()] = $met;
}
return $payload;
}
// What kind of access should the currently authenticated user have, given the
// provided groups (aka roles, permissions) associated with the resource?
//
// Possible values are: CasBrowser::{VIS_ALL, VIS_LIMIT, VIS_NONE}. It is up to the
// caller to determine what to do based on the return value
//
public static function ResourceVisibility( $resourceGroups ) {
// Is the resource considered "public"?
if (in_array(App::Get()->settings['browser_data_public_access'],$resourceGroups)) {
return CasBrowser::VIS_ALL;
}
// Get user authentication info
$authentication = App::Get()->getAuthenticationProvider();
$username = ($authentication)
? $authentication->getCurrentUsername()
: false; // no authentication info provided in config file
// Does the metadata visibility depend on an access element matching
// the `browser_data_access_key` in the config setting?
$accessKeyExists = isset(App::Get()->settings['browser_data_access_key']);
// If key is set then we look into what groups have access to metadata
if ( $accessKeyExists && !empty($resourceGroups) ) {
// Has authentication provider information been specified?
if ( $authentication ) {
// Is the user currently logged in?
if ( $username ) {
// Obtain the groups for the current user
$userGroups = App::Get()->getAuthorizationProvider()->retrieveGroupsForUser($username);
// Perform a comparison via array intersection to determine overlap
$x = array_intersect($userGroups,$resourceGroups);
if (empty($x)) { // No intersection found between user and resource groups
// Examine `browser_pt_auth_policy` to determine how to handle the failure
switch (strtoupper(App::Get()->settings['browser_pt_auth_policy'])) {
case "LIMIT":
// Allow the user to proceed, the metadata visibility policy
// will be used to determine what is visible to non-authorized
// users.
return CasBrowser::VIS_LIMIT;
case "DENY":
default:
// Kick the user out at this point, deny all access.
return CasBrowser::VIS_NONE;
}
} else {
// We have an authorized user
$authorizedUser = true;
}
} else {
// If no logged in user, and policy says DENY, kick the user
if (strtoupper(App::Get()->settings[$metType]) == "DENY") {
return CasBrowser::VIS_NONE;
} else {
return CasBrowser::VIS_LIMIT;
}
}
} else {
// If no authentication provider information exists in the application
// configuration file, it is assumed that authentication and authorization
// are not needed for this application, and thus every user is authorized
// by default.
return CasBrowser::VIS_ALL;
}
} else {
// All data is visible to user if logged in
// Has authentication provider information been specified?
if ( $authentication ) {
// Is the user currently logged in?
if ( $username ) {
return CasBrowser::VIS_ALL; // We have an authorized user
} else {
// If no logged in user, and policy says DENY, kick the user
if (strtoupper(App::Get()->settings[$metType]) == "DENY") {
return CasBrowser::VIS_NONE;
}
return CasBrowser::VIS_LIMIT;
}
} else {
// If no authentication provider information exists in the application
// configuration file, it is assumed that authentication and authorization
// are not needed for this application, and thus every user is authorized
// by default.
return CasBrowser::VIS_ALL;
}
}
}
// Create a criteria subtree that will search for the value at the given criteriaIndex across all
// metadata elements associated with the given productTypes.
public static function createBasicSearchSubtree($criteriaIndex, $queryTypes){
$criterion = new CAS_Filemgr_BooleanQueryCriteria();
$criterion->setOperator(CAS_Filemgr_BooleanQueryCriteria::$OR_OP);
$metadataNames = getMetadataElements($queryTypes);
foreach($metadataNames as $name){
$term = new CAS_Filemgr_TermQueryCriteria();
$term->setElementName($name);
$term->setValue($_POST['Criteria'][$criteriaIndex]['Value']);
$criterion->addTerm($term);
}
return $criterion;
}
public static function createTermCriteria($criteriaIndex, $queryTypes){
if(!isset($_POST['Criteria'][$criteriaIndex]['ElementName'])){
throw new CasBrowserException("Query Term criterion " . $criteriaIndex . " does not contain 'ElementName' specification");
}
if(!isset($_POST['Criteria'][$criteriaIndex]['Value'])){
throw new CasBrowserException("Query Term criterion " . $criteriaIndex . " does not contain 'Value' specification");
}
if($_POST['Criteria'][$criteriaIndex]['ElementName'] == '*'){
$criterion = self::createBasicSearchSubtree($criteriaIndex, $queryTypes);
}else{
$criterion = new CAS_Filemgr_TermQueryCriteria();
$criterion->setElementName($_POST['Criteria'][$criteriaIndex]['ElementName']);
$criterion->setValue($_POST['Criteria'][$criteriaIndex]['Value']);
}
return $criterion;
}
public static function createRangeCriteria($criteriaIndex){
if(!isset($_POST['Criteria'][$criteriaIndex]['ElementName'])){
throw new CasBrowserException("Query Term criterion " . $criteriaIndex . " does not contain 'ElementName' specification");
}
if(!isset($_POST['Criteria'][$criteriaIndex]['Min'])){
throw new CasBrowserException("Query Range criterion " . $criteriaIndex . " does not contain 'Min' specification");
}
if(!isset($_POST['Criteria'][$criteriaIndex]['Max'])){
throw new CasBrowserException("Query Range criterion " . $criteriaIndex . " does not contain 'Max' specification");
}
$criterion = new CAS_Filemgr_RangeQueryCriteria();
$criterion->setElementName($_POST['Criteria'][$criteriaIndex]['ElementName']);
$criterion->setStartValue($_POST['Criteria'][$criteriaIndex]['Min']);
$criterion->setEndValue($_POST['Criteria'][$criteriaIndex]['Max']);
if(isset($_POST['Criteria'][$criteriaIndex]['Inclusive'])){
$criterion->setInclusive($_POST['Criteria'][$criteriaIndex]['Inclusive']);
}
return $criterion;
}
public static function createBooleanCriteria($criteriaIndex, $queryTypes, $createdIndices){
if(!isset($_POST['Criteria'][$criteriaIndex]['Operator'])){
throw new CasBrowserException("Query Boolean criterion " . $criteriaIndex . " does not contain 'Operator' specification");
}
if(!isset($_POST['Criteria'][$criteriaIndex]['CriteriaTerms'])){
throw new CasBrowserException("Query Boolean criterion " . $criteriaIndex . " does not contain 'CriteriaTerms' specification");
}
if(!count($_POST['Criteria'][$criteriaIndex]['CriteriaTerms'])){
throw new CasBrowserException("Query Boolean criterion " . $criteriaIndex . " does not contain any terms");
}
$criterion = new CAS_Filemgr_BooleanQueryCriteria();
$operator = trim(strtoupper($_POST['Criteria'][$criteriaIndex]['Operator']));
if($operator == 'AND'){
$criterion->setOperator(CAS_Filemgr_BooleanQueryCriteria::$AND_OP);
}elseif($operator == 'OR'){
$criterion->setOperator(CAS_Filemgr_BooleanQueryCriteria::$OR_OP);
}elseif($operator == 'NOT'){
if(count($_POST['Criteria'][$criteriaIndex]['CriteriaTerms']) != 1){
throw new CasBrowserException("Query Boolean criterion " . $criteriaIndex . " cannot negate more than one term");
}
$criterion->setOperator(CAS_Filemgr_BooleanQueryCriteria::$NOT_OP);
}else{
throw new CasBrowserException("Error: Query Boolean criterion " . $criteriaIndex . " tries to use undefined operator '" . $operator . "'");
}
foreach(array_map("intval", $_POST['Criteria'][$criteriaIndex]['CriteriaTerms']) as $childIndex){
if(in_array($childIndex, $createdIndices)){ // Check for loops in criteria tree
throw new CasBrowserException("Criterion " . $criteriaIndex . " lists " . $childIndex . "as a child, making a loop.");
}
array_push($createdIndices, $childIndex);
$child = self::createCriteriaTree($childIndex, $queryTypes);
$criterion->addTerm($child);
}
return $criterion;
}
public static function createCriteriaTree($criteriaIndex, $queryTypes, $createdIndices=null){
if(!isset($createdIndices)){
$createdIndices = array();
}
if(!isset($_POST['Criteria'][$criteriaIndex])){
throw new CasBrowserException("Query Boolean criterion " . $criteriaIndex . " does not exist.");
}
$type = strtolower($_POST['Criteria'][$criteriaIndex]['CriteriaType']);
if($type == 'term'){
$criterion = self::createTermCriteria($criteriaIndex, $queryTypes);
}elseif($type == 'range'){
$criterion = self::createRangeCriteria($criteriaIndex);
}elseif($type == 'boolean'){
$criterion = self::createBooleanCriteria($criteriaIndex, $queryTypes, $createdIndices);
}else{
throw new CasBrowserException("Query criterion " . $criteriaIndex . " contains an unknown type " . $type . ". Please use one of 'term', 'range' or 'boolean'");
}
return $criterion;
}
public static function getMetadataNamesForTypeProducts($type){
$cb = new CasBrowser();
$client = $cb->getClient();
$elementNames = array();
foreach($client->getElementsByProductType($type) as $e){
array_push($elementNames, $e->getElementName());
}
foreach(array_keys($type->getTypeMetadata()->toAssocArray()) as $typeElementName){
if(!in_array($typeElementName, $elementNames)){
array_push($elementNames, $typeElementName);
}
}
return $elementNames;
}
public static function getFacets(){
$cb = new CasBrowser();
$client = $cb->getClient();
$types = $client->getProductTypes();
$facets = self::getMetadataNamesForTypeProducts(array_pop($types));
if(count($types) == 0){
return $facets; // In case there is only one product type
}
foreach($types as $type){
$elementNames = self::getMetadataNamesForTypeProducts($type);
$facets = array_intersect($facets, $elementNames);
}
return $facets;
}
public static function paginate($allProducts, $pageNum, $pageSize){
if(count($allProducts) == 0){
return array();
}
if($pageSize <= 0){
throw new CasBrowserException("The given PageSize (" . $pageSize . ") was zero or less.");
}
$startIndex = ($pageNum - 1) * $pageSize;
if($startIndex >= count($allProducts)){
throw new CasBrowserException("The starting index of the requested page (" .
$startIndex . ") is greater than the last index of all products (" .
count($allProducts) . ").");
}
$endIndex = $startIndex + $pageSize - 1;
$endIndex = min($endIndex, count($allProducts) - 1);
$requestedProducts = array();
for($i = $startIndex; $i <= $endIndex; $i++){
array_push($requestedProducts, $allProducts[$i]);
}
return $requestedProducts;
}
public static function formatResults($products){
$cb = new CasBrowser();
$client = $cb->getClient();
$results = array();
foreach($products as $product){
try{
$p = array('id'=>$product['product']->getId(),
'name'=>urlDecode($product['product']->getName()),
'metadata'=>$client->getMetadata($product['product'])->toAssocArray());
if(isset($product['typeName'])){
$p['type'] = $product['typeName'];
}
array_push($results, $p);
}catch(Exception $e){
throw new CasBrowserException("An error occured while formatting product [" .
$product['product']->getId() . "] metadata: " . $e->getMessage());
}
}
return $results;
}
public static function reportError($message, $outputFormat){
if($outputFormat == 'html'){
echo '<div class="error">' . $message . '</div>';
}elseif($outputFormat == 'json'){
$payload = array();
$payload['Error'] = 1;
$payload['ErrorMsg'] = $message;
$payload = json_encode($payload);
echo $payload;
}
exit();
}
}
class CasBrowserException extends Exception{}
?>