I am trying to create a dynamic endpoint for a API I am creating in order to include some data but only if it is required so I can use it in multiple places.
The idea is to have api.domain.com/vehicle to bring back basic vehicle information but if I did api.domain.com/vehicle?with=owners,history then the idea is to have a function which maps the owners and history to a class which will return data but only if it is required.
This is what I currently have.
public static function vehicle()
{
$with = isset($_GET['with']) ? $_GET['with'] : null;
$properties = explode(',', $with);
$result = ['vehicle' => Vehicle::data($id)];
foreach ($properties as $property) {
array_push($result, static::getPropertyResponse($property));
}
echo json_encode($result);
}
Which will then call this function.
protected static function getPropertyResponse($property)
{
$propertyMap = [
'owners' => Vehicle::owner($id),
'history' => Vehicle::history($id)
];
if (array_key_exists($property, $propertyMap)) {
return $propertyMap[$property];
}
return null;
}
However, the response I'm getting is being nested within a index, which I don't want it to be. The format I want is...
{
"vehicle": {
"make": "vehicle make"
},
"owners": {
"name": "owner name"
},
"history": {
"year": "26/01/2018"
}
}
But the format I am getting is this...
{
"vehicle": {
"make": "vehicle make"
},
"0": {
"owners": {
"name": "owner name"
}
},
"1": {
"history": {
"year": "26/01/2018"
}
}
}
How would I do this so it doesn't return with the index?
Vehicle::history($id) seems to return ['history'=>['year' => '26/01/2018']], ...etc.
foreach ($properties as $property) {
$out = static::getPropertyResponse($property) ;
$result[$property] = $out[$property] ;
}
Or your methods should returns something like ['year' => '26/01/2018'] and use :
foreach ($properties as $property) {
$result[$property] = static::getPropertyResponse($property) ;
}
Related
I'm currently stuck at this scenario, now the other developer wants to output the API structure as seen on attached image.
json_required_format
But I tried as far as I can but I only got these result:
"all_projects": {
"TEST TOWNHOMES": {
"unit_types": [
{
"unit": "TOWNHOUSE 44.00"
}
]
},
"TEST HOMES": {
"unit_types": [
{
"unit": "DUPLEX WITH OUT GARAGE 44.50"
}
]
},
"TEST HOMES II": {
"unit_types": [
{
"unit": "DUPLEX WITH OUT GARAGE 44.50"
}
]
},
"TEST VILLAGE": {
"unit_types": [
{
"unit": "TOWNHOUSE 44.00"
},
{
"unit": "DUPLEX WITHOUT GARAGE 52.30"
}
]
}
I am using MVC framework,
This is my model looks like:
public function all_south_projects()
{
$this->db->distinct();
return $this->db->select('Project as project_name')->from('lots')
->where('available','YES')
->get()->result();
}
public function get_unit_types($projName)
{
$this->db->distinct();
return $this->db->select('UnitType as unit')->from('lots')
->where('Project',$projName)
->where('Available','YES')
->get()->result();
}
And then my controller is:
$resp = $this->MyModel->all_south_projects();
$test_array = array();
foreach ($resp as $value) {
$units = $this->MyModel->get_unit_types($value->project_name);
$allunits = array("unit_types"=>$units);
$allunits = (object) $allunits;
$test_array[$value->project_name] = $allunits;
}
//var_dump($test_array);
$stat = 200;
$message = 'Successfully fetched.';
if(empty($test_array)){
$empty=json_decode('{}');
json_output2($stat,'all_projects',$message,$empty);
}else{
json_output2($stat,'all_projects',$message,$test_array);
}
json_output2 is on my helper to customize json format:
Here is my code:
function json_output2($statusHeader,$responseName,$message,$response)
{
$ci =& get_instance();
$ci->output->set_content_type('application/json');
$ci->output->set_status_header($statusHeader);
$ci->output->set_output(json_encode(array('status' =>
$statusHeader,'message' => $message,$responseName =>$response)));
}
NOTE: Scenario is:
The API must give all the projects having available units,
if the project is available, then it needs to get its corresponding available units to view. I know I can make another API call but this time, we need to improve the UX.
Can someone enlighten me to get through this? Thank you!
Change this part :
foreach ($resp as $value) {
$units = $this->MyModel->get_unit_types($value->project_name);
$allunits = array("unit_types"=>$units);
$allunits = (object) $allunits;
$test_array[$value->project_name] = $allunits;
}
To :
foreach ($resp as $value) {
$units = $this->MyModel->get_unit_types($value->project_name);
$test_array[] = [
"project_name" => $value->project_name,
"unit_types" => $units
];
}
You don't have to cast your associative array to object like you did there : $allunits = (object) $allunits; because an associative array will always be serialized as a JSON object (associative arrays do not exist in JSON).
Need to get campaign_id with the list_id that I've got. My goal is to get all the campaign data and then sort out using the list_id. I have been able to retrieve the campaign response body, but somehow failing to get the campaign list_id. Any help or a different approach would be appreciated. Sharing my code and mailchimp api related reference.
MailChimp api ref:
"campaigns": [
{
"id": "42694e9e57",
"type": "regular",
"create_time": "2015-09-15T14:40:36+00:00",
"archive_url": "http://",
"status": "save",
"emails_sent": 0,
"send_time": "",
"content_type": "template",
"recipients": {
"list_id": "57afe96172", // this is required
"segment_text": ""
},
My Progress:
public static function getCampaignID($list_id){
$MCcampaigninfo = self::$mc_api->get("/campaigns"); // gives a response consisting 3 rows, required value is in 1st row, which is an array
foreach ($MCcampaigninfo as $key => $value) {
if ($value[8]->'list_id' == $list_id) { //under the 'campaign'array, we need the 9th position property 'recipient'
$campaign_id = $value[12]->'id';
}
}
}
This code assumes the response of $mc_api->get is equal to the JSON you showed in your example
public static function getCampaignID($list_id) {
$campaigns = json_encode(self::$mc_api->get("/campaigns"), true);
$campaignIds = [];
foreach ($campaigns as $campaign) {
//if the list_id matches the current campaign recipients['list_id'] add to the array
if ($campaign['recipients']['list_id'] === $list_id) {
$campaignIds[] = $campaign['id'];
}
}
//return an array with campaignIds
return $campaignIds;
}
Got it working. The api structure seems different in reality from their documentation. Thanks for all the help. Posting my updated code.
public static function getCampaignID($list_id){
$MCcampaigninfo = self::$mc_api->get("/campaigns");
foreach ($MCcampaigninfo as $key => $campaign) {
if($key == campaigns){
foreach ($campaign as $key2 => $clist) {
foreach ($clist as $key3 => $recip) {
if($key3 == id){
$campaign_id = $recip;
}
elseif($key3 == recipients){
foreach($recip as $key4 => $listid){
if($key4 == list_id){
if($listid == $list_id){
return $campaign_id;
}
}
}
}
}
}
}
}
}
Let's say I have 2 functions that can call each other
public static function goToAction($action,$sender_id)
{
$actions = array();
$logic = file_get_contents('../../logic/logic.json');
$logic_array = json_decode($logic, true);
unset($logic);
if (!isset($logic_array[$action])) {
return false;
} else {
foreach ($logic_array[$action] as $action) {
$actions[] = self::parseActionType($action,$sender_id);
}
}
return $actions;
}
public static function parseActionType($actions,$sender_id)
{
$data = array();
foreach ($actions as $key => $action) {
switch ($key) {
case 'goto': {
$goto_actions = self::goToAction($action,$sender_id);
foreach ($goto_actions as $goto_action){
$data[] = $goto_action;
} break;
...
}
}
return $data;
}
and here is my json file:
"no_return": [
{ "text": "Должно быть: 1, 2, 3"},
{ "text": "1" },
{ "goto": "2nr", "no_return": true},
{ "text": "5" }
],
"2nr": [
{ "text": "2" },
{ "goto": "3", "no_return": true},
{ "text": "4"}
],
"3nr": [
{ "text": "3" }
],
it returns 12345 , and its right, but how can I make it return 123 if no_return is setted to true? Maybe function must return something?
foreach ($logic_array[$action] as $action) {
$actions[] = self::parseActionType($action,$sender_id);
if (!empty($action['no_return'])) { break; }
}
Using break inside of a loop stops it even if there are more element left, there is also continue this will end the current run and proceed with the next element.
I have a page that pulls information about TV shows from the TMDB as a json array with the help of the TMDB-API Wrapper. I am trying to get the page to display information on a tv shows's ['network'].
I have written a function for this that loops through the network array but I can't get it to work. Can anyone tell me what I'm doing wrong? Thanks.
This is my function that does not work.
//Get networks
public function getNetworks() {
$networks = array();
foreach($this->_data['networks'] as $data){
$networks[] = new Network($data, $this->getName());
}
return $networks;
}
Display.php
//Call the function and loop though results
echo ' <li>Networks: <ul>';
$networks = $tvShow->getNetworks();
foreach($networks as $network){
echo '<li>'. $network->getID() .'</li>';
}
This does work (written in the wrapper not me)
public function getSeasons() {
$seasons = array();
foreach($this->_data['seasons'] as $data){
$seasons[] = new Season($data, $this->getID());
}
return $seasons;
}
This does work
//Get Network
public function getNetworks() {
return $this->_data['networks'][0]['name'];
}
And then on display.php
echo '<b>'. $tvShow->getNetworks() .'</b>';
This is the json array
{
"backdrop_path": "/c8A5IYqIT1ez15sqA8wX5tCDTmF.jpg",
"created_by": [
{
"id": 1187819,
"name": "Matthew Weiner",
"profile_path": null
}
],
"episode_run_time": [
47,
45
],
"first_air_date": "2007-07-19",
"genres": [
{
"id": 18,
"name": "Drama"
}
],
"homepage": "http://www.amc.com/shows/mad-men",
"id": 1104,
"in_production": false,
"languages": [
"en"
],
"last_air_date": "2015-05-17",
"name": "Mad Men",
"networks": [
{
"id": 174,
"name": "AMC"
}
],
Tvshow Class
class TVShow{
//------------------------------------------------------------------------------
// Class Variables
//------------------------------------------------------------------------------
private $_data;
/**
* Construct Class
*
* #param array $data An array with the data of the TVShow
*/
public function __construct($data) {
$this->_data = $data;
}
I've set up a custom search action in my cakephp controller
public function search() {
$results = [];
$results['data'] = $this->Content->find('first',
array(
'conditions' => array($this->request->params['pass'][0] . ' like' => "%" . $this->request->params['pass'][1] . "%")), array('contain' => false)
);
if(count($results['data'])>0){
$results['success'] = true;
$this->set(compact('results'));
$this->set('_serialize', array('results'));
}
else{
$results['success'] = false;
}
}
The issue I'm running into is that the rest of my API formats data like this:
{
"success": true,
"data": [
{
"id": "5509be6c-9ef8-42c3-af39-2d492773a233",
"title": "test2",
},
{
"id": "5509be6c-9ef8-42c3-af39-2d492773a233",
"title": "test1"
}
]
}
but what I'm getting from cakephp right now for my search action is this:
{
"results": {
"success": true,
"data": {
"Content": {
"id": "52efcbeb-e984-4a2e-b76f-0cc34056922c",
"title": "Homeasdfasdf",
}
}
}}
How do I get rid of the extra "results" array wrapper so that my data is coming out in the same format?
Use the current() php function. In your controller make
$results = current($results);
before the set() call