on master help sign in
server side coding apparently not possibly, stalled changes for now
commitc8b3cfc9d7e67ca66dc3b2fd5e6853586ecd0f18 authorfriederjanmoerman <hijbrid@gmail.com> dateWed 26 Jun 2019, 13:09 (7 years ago) parent5ce94b1
5 files changed+529
static/php/airtable/hoonschool.php+3 static/php/airtable/src/Airtable.php+118 static/php/airtable/src/Request.php+155 static/php/airtable/src/Response.php+246 templates/hoonschool.html+7
static/php/airtable/hoonschool.phpnew file+3
@@ -0,0 +1,3 @@
1+<?php
2+ echo "test";
3+?>
static/php/airtable/src/Airtable.phpnew file+118
@@ -0,0 +1,118 @@
1+<?php
2+
3+namespace TANIOS\Airtable;
4+
5+/**
6+ * Airtable API Class
7+ *
8+ * @author Sleiman Tanios
9+ * @copyright Sleiman Tanios - TANIOS 2017
10+ * @version 1.0
11+ */
12+
13+
14+class Airtable
15+{
16+
17+ const API_URL = "https://api.airtable.com/v0/";
18+
19+ private $_key;
20+
21+ private $_base;
22+
23+ public function __construct($config)
24+ {
25+ if (is_array($config)) {
26+ $this->setKey($config['api_key']);
27+ $this->setBase($config['base']);
28+ } else {
29+ echo 'Error: __construct() - Configuration data is missing.';
30+ }
31+ }
32+
33+ public function setKey($key)
34+ {
35+ $this->_key = $key;
36+ }
37+
38+ public function getKey()
39+ {
40+ return $this->_key;
41+ }
42+
43+ public function setBase($base)
44+ {
45+ $this->_base = $base;
46+ }
47+
48+ public function getBase()
49+ {
50+ return $this->_base;
51+ }
52+
53+ public function getApiUrl($request){
54+ $request = str_replace( ' ', '%20', $request );
55+ $url = self::API_URL.$this->getBase().'/'.$request;
56+ return $url;
57+ }
58+
59+ function getContent($content_type,$params="",$relations=false)
60+ {
61+ return new Request( $this, $content_type, $params, false, $relations );
62+ }
63+
64+ function saveContent($content_type,$fields)
65+ {
66+
67+ $fields = array('fields'=>$fields);
68+
69+ $request = new Request( $this, $content_type, $fields, true );
70+
71+ return $request->getResponse();
72+
73+ }
74+
75+ function updateContent($content_type,$fields)
76+ {
77+
78+ $fields = array('fields'=>$fields);
79+
80+ $request = new Request( $this, $content_type, $fields, 'patch' );
81+
82+ return $request->getResponse();
83+
84+ }
85+
86+ function deleteContent($content_type)
87+ {
88+
89+ $request = new Request( $this, $content_type, [], 'delete' );
90+
91+ return $request->getResponse();
92+
93+ }
94+
95+ function quickCheck($content_type,$field="",$value="")
96+ {
97+ $params = "";
98+
99+ if (!empty($field)&& !empty($value)){
100+
101+ $params = array(
102+ "filterByFormula" => "AND({{$field}} = '$value')",
103+ );
104+ }
105+
106+ $request = new Request( $this, $content_type, $params, false );
107+
108+ $response = $request->getResponse();
109+
110+
111+ $results['count'] = count($response->records);
112+ $results['records'] = $response->records;
113+
114+
115+ return (object)$results;
116+ }
117+
118+}
static/php/airtable/src/Request.phpnew file+155
@@ -0,0 +1,155 @@
1+<?php
2+/**
3+ * Created by PhpStorm.
4+ * User: glali
5+ * Date: 2017-04-27
6+ * Time: 14:55
7+ */
8+
9+namespace TANIOS\Airtable;
10+
11+class Request implements \ArrayAccess
12+{
13+
14+ /**
15+ * @var Airtable Instance of Airtable
16+ */
17+ private $airtable;
18+ /**
19+ * @var resource Instance of CURL
20+ */
21+ private $curl;
22+ /**
23+ * @var string Content type
24+ */
25+ private $content_type;
26+ /**
27+ * @var array Request data
28+ */
29+ private $data = [];
30+ /**
31+ * @var bool Is it a POST request?
32+ */
33+ private $is_post = false;
34+
35+ /**
36+ * @var array|boolean Relations to lazy load
37+ */
38+ private $relations;
39+
40+ /**
41+ * Create a Request to AirTable API
42+ * @param Airtable $airtable Instance of Airtable
43+ * @param string $content_type Content type
44+ * @param array $data Request data
45+ * @param bool|string $is_post Is it a POST request?
46+ */
47+ public function __construct( $airtable, $content_type, $data = [], $is_post = false, $relations = false )
48+ {
49+
50+ $this->airtable = $airtable;
51+ $this->content_type = $content_type;
52+ $this->data = $data;
53+ $this->is_post = $is_post;
54+ $this->relations = $relations;
55+
56+ }
57+
58+ private function init()
59+ {
60+
61+ $headers = array(
62+ 'Content-Type: application/json',
63+ sprintf('Authorization: Bearer %s', $this->airtable->getKey())
64+ );
65+
66+ $request = $this->content_type;
67+
68+ if( ! $this->is_post )
69+ {
70+ if (!empty($this->data)){
71+ $data = http_build_query($this->data);
72+ $request .= "?" . $data;
73+ }
74+ }
75+
76+ $curl = curl_init($this->airtable->getApiUrl($request));
77+
78+ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
79+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
80+
81+ if( $this->is_post )
82+ {
83+ if( strtolower( $this->is_post ) == 'patch' )
84+ {
85+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
86+ }
87+ else if( strtolower( $this->is_post ) == 'delete' )
88+ {
89+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
90+ }
91+ curl_setopt($curl,CURLOPT_POST, count($this->data));
92+ curl_setopt($curl,CURLOPT_POSTFIELDS, json_encode($this->data));
93+ }
94+
95+ $this->curl = $curl;
96+
97+ }
98+
99+ /**
100+ * @return Response Get response from API
101+ */
102+ public function getResponse()
103+ {
104+
105+ $this->init();
106+
107+ $response_string = curl_exec( $this->curl );
108+
109+ $response = new Response( $this->airtable, $this, $response_string, $this->relations );
110+
111+ return $response;
112+
113+ }
114+
115+ public function __set( $key, $value )
116+ {
117+ if( ! is_array( $this->data ) )
118+ {
119+ $this->data = [];
120+ }
121+
122+ $this->data[ $key ] = $value;
123+ }
124+
125+ public function offsetExists($offset)
126+ {
127+ return is_array( $this->data) && isset( $this->data[ $offset ] );
128+ }
129+
130+ public function offsetGet($offset)
131+ {
132+ return is_array( $this->data ) && isset( $this->data[ $offset ] )
133+ ? $this->data[ $offset ]
134+ : null;
135+ }
136+
137+ public function offsetSet($offset, $value)
138+ {
139+ if( ! is_array( $this->data ) )
140+ {
141+ $this->data = [];
142+ }
143+
144+ $this->data[ $offset ] = $value;
145+ }
146+
147+ public function offsetUnset($offset)
148+ {
149+ if( is_array( $this->data ) && isset( $this->data[ $offset ] ) )
150+ {
151+ unset( $this->data[ $offset ] );
152+ }
153+ }
154+
155+}
static/php/airtable/src/Response.phpnew file+246
@@ -0,0 +1,246 @@
1+<?php
2+/**
3+ * Created by PhpStorm.
4+ * User: glali
5+ * Date: 2017-04-27
6+ * Time: 14:44
7+ */
8+
9+namespace TANIOS\Airtable;
10+
11+
12+class Response implements \ArrayAccess
13+{
14+
15+ /**
16+ * @var Airtable Instance of Airtable
17+ */
18+ private $airtable;
19+
20+ /**
21+ * @var Request Instance or Request
22+ */
23+ private $request;
24+
25+ /**
26+ * @var string Response content
27+ */
28+ private $content = "";
29+
30+ /**
31+ * @var bool|\stdClass Response
32+ */
33+ private $parsedContent = false;
34+
35+ /**
36+ * Response constructor.
37+ * @param Airtable $airtable Instance of Airtable
38+ * @param Request $request Instance of Request
39+ * @param string $content Content string
40+ */
41+ public function __construct( $airtable, $request, $content, $relations = false )
42+ {
43+
44+ $this->airtable = $airtable;
45+
46+ $this->request = $request;
47+
48+ $this->content = $content;
49+
50+ try
51+ {
52+ $this->parsedContent = json_decode( $content );
53+ }
54+ catch ( \Exception $e )
55+ {
56+ $this->parsedContent = false;
57+ }
58+
59+ if( is_array( $relations ) && count( $relations ) > 0 )
60+ {
61+
62+ if( array_keys( $relations ) !== range( 0, count( $relations ) - 1 ) )
63+ {
64+ foreach ( $relations as $related_field => $related_table )
65+ {
66+ $this->processRelatedField( $related_field, $related_table );
67+ }
68+ }
69+ else
70+ {
71+ foreach ( $relations as $related_field )
72+ {
73+ $this->processRelatedField( $related_field );
74+ }
75+ }
76+
77+ }
78+
79+ }
80+
81+ private function processRelatedField( $related_field, $related_table = false )
82+ {
83+
84+ if( isset( $this->parsedContent->records ) && is_array( $this->parsedContent->records ) && count( $this->parsedContent->records ) > 0 )
85+ {
86+ foreach ( $this->parsedContent->records as $record_key => $record )
87+ {
88+ $this->parsedContent->records[ $record_key ] = $this->loadRelatedField( $related_field, $related_table, $record );
89+ }
90+ }
91+ else
92+ {
93+ $this->parsedContent = $this->loadRelatedField( $related_field, $related_table, $this->parsedContent );
94+ }
95+
96+ }
97+
98+ private function loadRelatedField( $related_field, $related_table, $record )
99+ {
100+
101+
102+ if( ! isset( $record->fields ) || ! isset( $record->fields->$related_field ) )
103+ {
104+ return $record;
105+ }
106+
107+ if( empty( $related_table ) )
108+ {
109+ $related_table = $related_field;
110+ }
111+
112+ $relation_ids = $record->fields->$related_field;
113+
114+ if( ! is_array( $relation_ids ) )
115+ {
116+ $relation_ids = [ $relation_ids ];
117+ }
118+
119+ $relation_formula = "OR(";
120+ $relation_formula .= implode( ', ', array_map( function( $id ) { return "RECORD_ID() = '$id'"; }, $relation_ids ) );
121+ $relation_formula .= ")";
122+
123+ if( ! is_array( $related_table ) )
124+ {
125+ $relation_request = $this->airtable->getContent( "$related_table", [
126+ 'filterByFormula' => $relation_formula
127+ ] );
128+ }
129+ else
130+ {
131+ $related_table_relations = isset( $related_table[ 'relations' ] ) && is_array( $related_table[ 'relations' ] )
132+ ? $related_table[ 'relations' ]
133+ : false;
134+
135+ $related_table_name = ! empty( $related_table[ 'table' ] ) ? $related_table[ 'table' ] : $related_field;
136+
137+ $relation_request = $this->airtable->getContent( "$related_table_name", [
138+ 'filterByFormula' => $relation_formula
139+ ], $related_table_relations );
140+ }
141+
142+
143+ $related_records = [];
144+
145+ do
146+ {
147+ $relation_response = $relation_request->getResponse();
148+
149+ if( ! is_array( $relation_response->records ) || count( $relation_response->records ) < 0 )
150+ {
151+ break;
152+ }
153+
154+ foreach ( $relation_response->records as $related_record )
155+ {
156+ $formatted_record = $related_record->fields;
157+ $formatted_record->id = $related_record->id;
158+
159+ $related_records[] = $formatted_record;
160+ }
161+ }
162+ while( $relation_request = $relation_response->next() );
163+
164+ if( is_array( $record->fields->$related_field ) )
165+ {
166+ $record->fields->$related_field = $related_records;
167+ }
168+ else
169+ {
170+ $record->fields->$related_field = count( $related_records ) > 0
171+ ? $related_records[ 0 ]
172+ : null;
173+ }
174+
175+ return $record;
176+
177+ }
178+
179+ public function next()
180+ {
181+
182+ if( ! $this->parsedContent )
183+ {
184+ return false;
185+ }
186+
187+
188+ if( ! isset( $this[ 'offset' ] ) )
189+ {
190+ return false;
191+ }
192+
193+ $this->request->offset = $this[ 'offset' ];
194+
195+ return $this->request;
196+
197+ }
198+
199+ public function __get( $key )
200+ {
201+ if( ! $this->parsedContent || ! isset( $this->parsedContent->$key ) )
202+ {
203+ return null;
204+ }
205+
206+ return $this->parsedContent->$key;
207+ }
208+
209+ public function __toString()
210+ {
211+ return $this->content;
212+ }
213+
214+ public function __isset( $key )
215+ {
216+ return $this->parsedContent && isset( $this->parsedContent->$key );
217+ }
218+
219+ public function offsetExists($offset)
220+ {
221+ return $this->parsedContent && isset( $this->parsedContent->$offset );
222+ }
223+
224+ public function offsetGet($offset)
225+ {
226+ return $this->parsedContent && isset( $this->parsedContent->$offset )
227+ ? $this->parsedContent->$offset
228+ : null;
229+ }
230+
231+ public function offsetSet($offset, $value)
232+ {
233+ if( $this->parsedContent )
234+ {
235+ $this->parsedContent->$offset = $value;
236+ }
237+ }
238+
239+ public function offsetUnset($offset)
240+ {
241+ if( $this->parsedContent && isset( $this->parsedContent->$offset ) )
242+ {
243+ unset( $this->parsedContent->$offset );
244+ }
245+ }
246+}
templates/hoonschool.html+7
@@ -54,6 +54,13 @@
5454 </button>
5555 </div>
5656 </form>
57+
58+ <!--<form action="{{ config.base_url }}/php/airtable/hoonschool.php" method="POST">
59+ Name: <input type="text" name="name" />
60+ Age: <input type="text" name="age" />
61+ <input type="submit" />
62+ </form>-->
63+
5764 </article>
5865 </div>
5966 </div>