· 5 years ago · Dec 03, 2020, 02:56 PM
1<?php
2/**
3 * Class WebService
4 */
5namespace Zizu\Bildeleksperten\TecDoc;
6use Zizu\Bildeleksperten\TecDoc\Helper;
7use Zizu\Bildeleksperten\TecDoc\Filters;
8
9/**
10 * Connect to TecAlliance's TecDoc and grab any information.
11 *
12 * @package ZIZU\Wordpress\TecDoc
13 * @subpackage WebService
14 * @author Stian Jacobsen
15 * @copyright ZIZU
16 * @version 1.1.6
17 */
18class WebService
19{
20 /**
21 * TecDoC API Url
22 */
23 const URI = 'https://webservice.tecalliance.services/pegasus-3-0/services/TecdocToCatDLB.jsonEndpoint';
24
25 /**
26 * TecDoC Documents Url
27 */
28 const ASSETS_URI = 'https://webservice.tecalliance.services/pegasus-3-0/documents';
29
30 /**
31 * TecDoc Language Attribute
32 */
33 const LNG = 'NO';
34
35 /**
36 * Cache Time-to-live
37 */
38 const CACHE_TTL = 863600;
39
40 /**
41 * @var string TecDoC Provider ID
42 */
43 protected $provider;
44
45 /**
46 * @var string Holds the last Error
47 */
48 public $error;
49
50 /**
51 * @var array Holds the last request parameters
52 */
53 public $request_params;
54
55 /**
56 * @var mixed Holds the last request response
57 */
58 private $current_response;
59
60 /**
61 * @var mixed Holds the last request status
62 */
63 private $current_status;
64
65
66 /**
67 * Class constructor
68 * @param $provider integer TecDoc ProviderID
69 * @return void
70 */
71 public function __construct( $provider = null )
72 {
73 $this->provider = $provider;
74 Helper::cache_prefix( $provider );
75 }
76
77 /**
78 * Make an generic request to TecDoc.
79 *
80 * @uses send_request()
81 * @param string $method TecDoc Functionname for endpoints
82 * @param array $params Paramenters to pass along to tecdoc
83 * @param boolean $cache Cache the request
84 * @return mixed Object or false if requests fails
85 */
86 public function request( $method = null, $params = array(), $cache = true )
87 {
88 $ck = md5('request:'.$method.'--'.serialize($params));
89 if( true === $cache ) {
90
91 $data = Helper::check_cache($ck);
92 if( false === $data ) {
93 $request = $this->send_request($method, $params);
94 $data = Helper::set_cache( $ck, $request, self::CACHE_TTL );
95 }
96 return $data;
97 } else {
98 Helper::delete_cache( $ck );
99 return $this->send_request($method, $params);
100 }
101 }
102
103 /**
104 * Get Manufacturers
105 * List all Car manufactors in the TecDoc database.
106 * @param integer $favList Show only favoured list (Manufacturer filter must be sent to TecAllianace).
107 * @return mixed Array with objects: manufacturer ID (manuId) and manufacturer name (manuName) on success. False on error
108 */
109 public function getManufacturers( $favList = 1 )
110 {
111 return $this->request( 'getManufacturers', ["linkingTargetType" => "PO", "favouredList" => $favList ] );
112 }
113
114 public function linkedInformation( $id = null )
115 {
116 return $this->request( 'ArticlePartListRequest ', ["linkingTargetType" => "PO", "articleId" => $id ] );
117 }
118
119 /**
120 * Key Value Table
121 * Lookup the KV-Table in TecDoc
122 * @param integer $table_id The Table ID
123 * @param integer $key_id The Key ID (For single use)
124 * @return mixed The Value of key_id is set, or all values if not
125 */
126 public function kvt( $table_id = null, $key_id = null )
127 {
128 if( empty( $table_id ) )
129 return false;
130
131 $get = $this->request( 'getKeyValues', ["keyTableId" => $table_id ] );
132 if( empty( $key_id ) )
133 return $get;
134
135 $res = false;
136 foreach ($get as $row) {
137 if( $row->keyId == $key_id ) {
138 $res = $row->keyValue;
139 continue;
140 }
141 }
142
143 return $res;
144
145 }
146
147 public function test( $ID )
148 {
149 #$this->getArticlesFromCategory( $node_id, $brand_id, $article_id, $car_id = null )
150 }
151
152 /**
153 * Get Models
154 * List all models from a spesific manufactor in the TecDoc database.
155 * @param integer $id Manufacturer ID (manuId)
156 * @param integer $indexByID Return the array with Model-ID as Index
157 * @return mixed Array or false on error
158 */
159 public function getModels( $id = null, $indexByID = false )
160 {
161 $vehicles = [];
162 $get = $this->request( 'getModelSeries', ["linkingTargetType" => "PO", "manuId"=>$id ] );
163 if( false !== $get && isset($get ) ) {
164
165 $filtered = Helper::check_cache( 'getModelSeriesFiltered__'.$id.(true==$indexByID?'indexed':'normal') );
166 if( !$filtered ) {
167 foreach ($get as $models) {
168
169 $name = trim( preg_replace("/\([^)]+\)/","",$models->modelname) ); // Removes the ( )
170 if( strrpos($name, "(") !== false ) {
171 $name = explode("(", $name, 2);
172 $name = trim($name[0]);
173 }
174
175 $__id = true === $indexByID ? $models->modelId : $name;
176 $to_year = isset( $models->yearOfConstrTo ) ? substr($models->yearOfConstrTo, 0, 4) : date("Y");
177 $to_month = isset( $models->yearOfConstrTo ) ? substr($models->yearOfConstrTo, -2) : date("m");
178
179
180 if( !isset($vehicles[$name]) ) {
181 $vehicles[$__id] = [
182 'id'=>$models->modelId,
183 'variants'=>null,
184 'name'=>$name,
185 'original'=>$models->modelname,
186 'from_year'=>(int) substr($models->yearOfConstrFrom, 0, 4),
187 'from_month'=>(int) substr($models->yearOfConstrFrom, -2),
188 'to_year'=>(int) $to_year,
189 'to_month'=>(int) $to_month,
190 ];
191 } else {
192
193 $variant = $this->cleanVariantName( $models->modelname );
194 $vehicles[$__id]['variants'] = $variant;
195 $start = (int) substr($models->yearOfConstrFrom, 0, 4);
196 $startm= (int) substr($models->yearOfConstrFrom, -2);
197 $end = (int) $to_year;
198 $endm = (int) $to_month;
199 if( $start < $vehicles[$__id]['from_year'] ) {
200 $vehicles[$__id]['from_year'] = $start;
201 if( $startm < $vehicles[$__id]['from_month'] ) {
202 $vehicles[$__id]['from_month'] = $startm;
203 }
204 }
205 if( $end > $vehicles[$__id]['to_year'] ) {
206 $vehicles[$__id]['to_year'] = $end;
207 if( $endm < $vehicles[$__id]['to_month'] ) {
208 $vehicles[$__id]['to_month'] = $endm;
209 }
210 }
211
212 }
213 }
214 if( false == $indexByID ) {
215 $vehicles = array_values(array_filter($vehicles));
216 }
217 $filtered = Helper::set_cache( 'getModelSeriesFiltered__'.$id.(true==$indexByID?'indexed':'normal') , $vehicles, self::CACHE_TTL );
218 }
219 return $filtered;
220 }
221 return false;
222 }
223
224 /**
225 * Get producionyear of a given model
226 * @param integer $id Manufactor ID
227 * @param mixed $model Model (ID or Name)
228 * @return array List of years
229 */
230 public function getProductionYears( $id = null, $model = null )
231 {
232 $models = $this->getModels($id, true );
233 $find = $models[$model];
234 return $this->getYears( $find['from_year'], $find['to_year'] );
235 }
236
237 /**
238 * Get Vehicles
239 * List all vehicles from a spesific manufactor and Model in the TecDoc database.
240 * @param integer $manufactorID Manufacturer ID
241 * @param integer $modelID Model ID
242 * @param integer $year Show only year
243 * @return mixed Array or false on error
244 */
245 public function getVehicles( $manufactorID = null, $modelID = null, $year = null )
246 {
247 $args = [
248 "carType" => "PO",
249 "manuId" => $manufactorID,
250 "modId" => $modelID,
251 "countriesCarSelection" => self::LNG
252 ];
253 if( !empty($year) ) {
254 $args['yearOfConstruction'] = $year;
255 }
256 return $this->request( 'getVehicleIdsByCriteria', $args );
257 }
258
259
260
261
262 /**
263 * Get details about car by manufactor ID
264 * @param integer $id Manufactor ID
265 * @param boolean $direct Do a direct look-up
266 * @return array Returns array on success, false if not
267 */
268 public function getCarByID( $id = null, $direct = false )
269 {
270 global $wpdb;
271 $ids['array'] = is_array( $id ) ? $id : array($id); // TecDoc expects arrays to pre named, array
272
273 if( $direct === false ) {
274 /*
275'manufactorId' => $car->manuId,
276 'manufactor' => $car->manuName,
277 'model'=> $car->modelName,
278 'modelname' => $this->removeVariantName( $car->modelName ),
279 'modelId' => $car->modId,
280
281 */
282
283 if( $from_db = $wpdb->get_results("SELECT * FROM ".$wpdb->prefix."tecdoc_cars WHERE car_id = '".$id."'") ) {
284 #echo 'db';
285 $fixed_from_db = [
286 'manuName'=>$from_db[0]->car_brand,
287 'modelName'=>$from_db[0]->car_modelname,
288 'typeName'=>$from_db[0]->car_type,
289 'fuelType'=>$from_db[0]->car_fuel,
290 'modId'=>$from_db[0]->car_modid,
291 'modelId'=>$from_db[0]->car_modid,
292 'manufactorId'=>$from_db[0]->car_manuid,
293 'manuId'=>$from_db[0]->car_manuid
294 ];
295
296 if( empty( $from_db[0]->car_modid ) || empty( $from_db[0]->car_manuid ) ) {
297 #echo 'empty';
298 $new = $this->getCarByID( $id, true );
299 #var_dump($new);
300 #exit;
301 $wpdb->update( $wpdb->prefix."tecdoc_cars", ['car_modid'=>$new->modId,'car_manuid'=>$new->manuId], ['car_id'=>$id] );
302 $fixed_from_db['modId'] = $fixed_from_db['modelId'] = $new->modId;
303 $fixed_from_db['manufactorId'] = $fixed_from_db['manuId'] = $new->manuId;
304 }
305
306 $fixed_from_db['carId'] = $id;
307 return (object) $fixed_from_db;
308 }
309 }
310
311 // Change the request to getVehicleByIds3??
312 $search = $this->request( 'getVehicleByIds4', [
313 "articleCountry" => self::LNG,
314 "motorCodes" => true,
315 "kbaData" => true,
316 "axles" => true,
317 "cabs"=>true,
318 "registrationInfo"=>true,
319 "wheelbases"=>true,
320 "secondaryTypes"=>true,
321 "countriesCarSelection" => self::LNG,
322 "carIds"=>$ids
323 ], true);
324
325 if( false === $search ) {
326 return false;
327 }
328
329 #var_dump( $search );
330
331 if( count( $search ) > 1 ) {
332 $ret = [];
333 foreach( $search as $s) {
334 if( isset( $s->motorCodes->array ) ) {
335 $s->vehicleDetails->motorCode = $this->parseMotorcodes( $s );
336 }
337 $this->insert_to_car_db( $s->vehicleDetails );
338 $ret[] = $s->vehicleDetails;
339 }
340 return $ret;
341 } else {
342 if( isset( $search[0]->motorCodes->array ) ) {
343 $search[0]->vehicleDetails->motorCode = $this->parseMotorcodes( $search[0] );
344 }
345 $this->insert_to_car_db( $search[0]->vehicleDetails );
346 return $search[0]->vehicleDetails;
347 }
348 }
349
350 /**
351 * Get simplified details about car by manufactor ID
352 * To get full details, use the ´getCarByID´ method
353 * @uses WebService::getCarByID()
354 * @param integer $id Manufactor ID
355 * @return object
356 */
357 public function getVehicle( $id, $direct = false )
358 {
359 $key = 'getVehicleByID_'.$id;
360 //Helper::delete_cache($key);
361 $car = Helper::check_cache( $key );
362 if( false === $car || empty($car) || empty($car->modelId ) || empty( $car->manufactorId ) ) {
363 $car = $this->getCarByID( $id, $direct );
364 if( $car ) {
365 $data = (object) [
366 'id' => $car->carId,
367 'name' => $car->manuName." ".rtrim($this->removeVariantName( $car->modelName ))." ".$car->typeName,
368 'logo' => strtolower( $this->cleanString( $car->manuName ) ) .".png",
369 'manufactorId' => $car->manuId,
370 'manufactor' => $car->manuName,
371 'model'=> $car->modelName,
372 'modelname' => $this->removeVariantName( $car->modelName ),
373 'modelId' => $car->modId,
374 'type'=>$car->typeName,
375 'typeId'=>$car->typeNumber,
376 'costruction'=>$car->constructionType,
377 'fuel'=>$car->fuelType,
378 'engine'=>(is_array($car->motorCode) ? implode(", ", $car->motorCode) : $car->motorCode),
379 'hp'=>$car->powerHpFrom,
380 'kw'=>$car->powerKwFrom,
381 'volum'=>$car->cylinderCapacityCcm,
382 'liters'=>$car->cylinderCapacityLiter,
383 'cylinders'=>$car->cylinder,
384 'drive'=>$car->impulsionType,
385 'from'=>$this->filterProductionYears($car->yearOfConstrFrom, 'y'), // mb_substr($car->yearOfConstrFrom, 0, 4),
386 'from_month'=>$this->filterProductionYears($car->yearOfConstrFrom, 'm'), //mb_substr($car->yearOfConstrFrom, 4, 2),
387 'to'=>$this->filterProductionYears($car->yearOfConstrTo, 'y'),//mb_substr($car->yearOfConstrTo, 0, 4),
388 'to_month'=>$this->filterProductionYears($car->yearOfConstrTo, 'm')//mb_substr($car->yearOfConstrTo, 4, 2),
389 ];
390 // INSERT TO DATABASE FOR BETTER STORAGE
391
392
393 return Helper::set_cache( $key, $data, self::CACHE_TTL );
394 }
395 return false;
396 }
397 return $car;
398 }
399
400 /**
401 * Search TecDoc DB to get linked IDs matching the TecDocId
402 * @param integer $tecdocid
403 * @param integer $brandID
404 * @param integer $carID
405 * @param integer $catID
406 * @return object
407 */
408 public function getLinkedID( $tecdocid = null, $brandID = null, $carID = null, $catID = null)
409 {
410 $request = $this->request( 'getArticleIdsWithState', [
411 'assemblyGroupNodeId'=>'',
412 'brandNo'=>['array'=> $brandID], // Brand ID - SIDEM
413 'linkingTargetId' => $carID, // Car ID
414 'genericArticleId'=>['array'=>$catID], // TecDoc Category
415 'linkingTargetType'=>'P'
416 ], true);
417
418 if( false !== $request || !empty( $request->data) ) {
419 $response = false;
420 foreach ($request as $row) {
421 if( $row->articleId == $tecdocid ) {
422 $response = $row;
423 continue;
424 }
425 }
426 return $response;
427 }
428
429 return false;
430 }
431
432 public function getCarSpesificAttributes( $elm, $carId = null, $manuId = null, $modId = null )
433 {
434 $attributs = $this->request( 'getAssignedArticlesByIds7', [
435 'articleIdPairs'=>[
436 'array'=> [
437 'articleId'=>$elm->articleId,
438 'articleLinkId'=>$elm->articleLinkId
439 ]
440 ],
441 'linkingTargetId' => $carId,
442 'linkingTargetType'=>'P',
443 'attributs'=>1,
444 'manuId'=>$manuId,
445 'modId'=>$modId
446 ], true);
447 if( false !== $attributs || !empty( $attributs->data) ) {
448
449 if( isset( $attributs[0]->articleAttributes->array ) ) {
450 return $attributs[0]->articleAttributes->array;
451 }
452 return false;
453
454 }
455 return false;
456 }
457
458 /**
459 * Filter date of productions
460 * @param string $input Date string
461 * @param string $r Return method, Y or M (Optional)
462 * @return mixed Returns Array if no Return-type is set or string with filtered date
463 */
464 public function filterProductionYears($input,$r=null)
465 {
466 $pd = [
467 'y'=>mb_substr($input, 0, 4),
468 'm'=>mb_substr($input, 4, 2)
469 ];
470 if( $r === null || !array_key_exists($r, $pd) )
471 return $pd;
472
473 return $pd[$r];
474 }
475
476
477 /**
478 * Get all linked Vehicles from an Article ID
479 * This is the main function for getting a list of linked cars
480 * @param integer $artID Article ID
481 * @param boolean $detailed Show detailed list of cars (Or just the basic linkage )
482 * @return object
483 */
484 public function getLinkedVehicles( $artID = null, $detailed = false )
485 {
486 $list = $this->request( 'getArticleLinkedAllLinkingTarget3', ['articleId'=>$artID,'linkingTargetType'=>'PO'] );
487 #exit(1);
488 #echo $this->getError();
489 if( $detailed === true ) {
490 $all = $list[0]->articleLinkages->array;
491 $i=0;
492 if( is_array($all) ) {
493 foreach ($all as $l) {
494 $all[$i]->details = $this->getVehicle( $l->linkingTargetId );
495 $i++;
496 }
497 return $all;
498 }
499 return array();
500 }
501
502 return $list[0]->articleLinkages->array;
503 }
504
505 /**
506 * Get all linked Vehicles from an Article ID grouped by manufactor
507 *
508 * @param integer $artID Article ID
509 * @param boolean $detailed Show detailed list of cars (Or just the basic linkage )
510 * @return object
511 */
512 public function getGroupedLinkedVehicles( $artID = null, $detailed = true )
513 {
514
515 $key = 'getGroupedLinkedVehicles('.$artID.')' . ($detailed == true ? 'detailed' : 'undetailed');
516 $list = Helper::check_cache( $key );
517
518 if( !$list ) {
519 $all = $this->getLinkedVehicles($artID, $detailed);
520 if( is_array($all) ) {
521 if( $detailed == true ) {
522 $grp = [];
523 foreach ($all as $link) {
524 $d = $link->details;
525 $grp[$d->manufactor][] = $d;
526 }
527 } else {
528 $grp = $all;
529 }
530 return Helper::set_cache( $key, $grp, self::CACHE_TTL );
531 }
532 return false;
533 }
534 return $list;
535
536 }
537
538
539 /**
540 * Show car full name (ie. Volkswagen Touran 1.9 TDI 150Hk 2010 (Disel) )
541 * @param integer $id Car ID
542 * @param integer $year Make year (optional)
543 * @return string
544 */
545 public function getCarNicename( $id, $year = null )
546 {
547 $car = $this->getCarByID( $id );
548 if( $car ) {
549 $variant = $this->cleanVariantName( $car->modelName );
550 return $car->manuName." ".$car->modelName." ".$car->typeName." ".(!empty($year)?$year." ":null)."(".$car->fuelType.")";
551 }
552 }
553
554 /**
555 * Show car full name (ie. Volkswagen Touran 1.9 TDI 150Hk 2010 (Disel) )
556 * @deprecated 1.0.5 No longer used by internal code and not recommended. Use ´getCarNicename'
557 * @param object $vehicle TecDoc vehicle object
558 * @param boolean $fullModelName Show full model name?
559 * @return string
560 */
561 public function getCarName( $vehicle = null, $fullModelName = false )
562 {
563 if( !is_object( $vehicle ) )
564 $vehicle = $this->getCarByID( $vehicle );
565
566 if( $vehicle ) {
567 $m = false === $fullModelName ? $this->removeVariantName( $vehicle->modelName ) : $vehicle->modelName;
568 return $vehicle->manuName." ".rtrim( $m )." ".$vehicle->typeName;
569 }
570 return false;
571 }
572
573 /**
574 * Get information of an "AM" Brand (After-market)
575 * @param integer $id Brand ID
576 * @return array
577 */
578 public function getBrandInfo( $id )
579 {
580 return $this->request( 'getAmBrandAddress', [
581 "articleCountry" => self::LNG,
582 "brandNo" => $id,
583 ]);
584 }
585
586 /**
587 * Get all available brands
588 * @return array
589 */
590 public function getAvailableBrands()
591 {
592 return $this->request( 'getAmBrands' );
593 }
594
595 /**
596 * Get total amount of available products
597 * @param integer $brandID Brand ID
598 * @return integer
599 */
600 public function countAvailableProducts( $brandID = null )
601 {
602 $query = $this->request( 'getArticles', ['dataSupplierIds'=>$brandID,'perPage'=>1,'page'=>1] );
603 if( $query->totalMatchingArticles && $query->status == 200 ) {
604 return $query->totalMatchingArticles;
605 } else {
606 return 0;
607 }
608 }
609
610 /**
611 * Get Logo of Brand
612 * @param integer $id Brand ID
613 * @return string Url to Brand logo
614 */
615 public function getBrandLogo( $id = null )
616 {
617 return $this->getImage( $id );
618 }
619
620 /**
621 * Get Articles from brand
622 * @param integer $brandID Brand ID
623 * @param integer $page Page number
624 * @param array $args Arguments
625 * @return object
626 */
627 public function getArticles( $brandID = null, $page = 1, $args = array() )
628 {
629
630 $total = $this->countAvailableProducts( $brandID ); // Total amount of products
631 $perpage = isset($args['perpage']) && !empty($args['perpage']) && is_numeric($args['perpage']) ? $args['perpage'] : 25; // Products per page
632 $max = ceil( $total / $perpage );
633
634 $params = [];
635 $params['dataSupplierIds'] = $brandID;
636 $params['perPage'] = $perpage;
637 $params['page'] = $page < 1 ? 1 : ($page > $max ? $max : $page );
638 #$params['_maxNumPages'] = $max;
639 // What information to show
640 $params['includeArticleCriteria'] = isset($args['attributes']) && !empty($args['attributes']) && $args['attributes'] == true ? true : false; // Return product attributes
641
642 if( $args['q'] ) {
643 $params['searchQuery'] = $args['q'];
644 }
645 $result = $this->request( 'getArticles', $params );
646 if( $result->articles ) {
647 return $result->articles;
648 }
649
650 }
651 /**
652 * Get Article Information
653 * @param integer $articleId The TecDOC Article ID
654 * @return object
655 */
656 public function getArticleData( $articleId = null )
657 {
658 if( empty( $articleId ) )
659 return null;
660
661 $find = $this->request( 'getDirectArticlesByIds6', [
662 'articleId'=>['array'=> (int) $articleId],
663 'attributs'=>true,
664 'basicData'=>true,
665 'documents'=>true,
666 'eanNumbers'=>true,
667 #'immediateAttributs'=>true,
668 'immediateInfo'=>false,
669 'info'=>true,
670 'mainArticles'=>true,
671 #'normalAustauschPrice'=>true,
672 'oeNumbers'=>true, // Finding cars that fits
673 'prices'=>true,
674 'normalAustauschPrice'=>true,
675 'provider'=>20827,
676 'replacedByNumbers'=>true,
677 'replacedNumbers'=>true,
678 #'thumbnails'=>true,
679 'usageNumbers'=>true
680 ]);
681
682 if( isset( $find->data ) && empty( $find->data) ) {
683 return false;
684 }
685
686 if( $find && count($find) == 1 && !isset($find->data) ) {
687 return $this->filterArticleRequest($find[0]);
688 }
689 return $this->filterArticleRequest($find);
690 }
691
692 /**
693 * Filter response from ´getDirectArticlesByIds6´
694 * @param object $article Article
695 * @return object
696 */
697 private function filterArticleRequest( $article )
698 {
699 if( is_array($article) ) {
700 $f = [];
701 foreach ($article as $a) {
702 $f[] = $this->filterArticleRequest( $a );
703 }
704 return $f;
705 }
706
707 // Fix images so they show full path
708 $docs = $article->articleDocuments->array;
709 if( is_array($docs) ) {
710 $res = [];
711 foreach ($docs as $m) {
712 $res[] = ['id'=>$m->docId,'filename'=>$m->docFileName,'url'=>$this->getImage($m->docId)];
713 }
714 $article->documents = $res;
715 }
716 return $article;
717 }
718
719 /**
720 * Get all Images from Article
721 * @param mixed $article Use ArticleId or Article [Object]
722 * @param boolean $onlyimages Return ONLY images
723 * @return object
724 */
725 public function getArticleMedia( $article, $onlyimages = false )
726 {
727 if( empty($article) )
728 return false;
729
730 if( !is_object($article) && !is_array($article) && is_numeric( $article ) ) {
731 $article = $this->getArticleData( $article );
732 }
733 $cache_key = 'getArticleMedia-'.$article->directArticle->articleId;
734
735 if( isset($article->documents) && !empty($article->documents) ) {
736 if( true === $onlyimages ) {
737
738 $new = [];
739 foreach ($article->documents as $imgs) {
740 #var_dump( $imgs );
741 if( self::is_image( $imgs['filename'] ) ) {
742 #echo 1;
743 $new[] = $imgs;
744 }
745 }
746 return $new;
747 }
748 return $article->documents;
749 }
750
751 $cache = Helper::check_cache( $cache_key );
752 if( !$cache ) {
753 // Find media objects
754 $media = $article->articleDocuments->array;
755 if( is_array($media) ) {
756 $res = [];
757 foreach ($media as $m) {
758 #$_split = explode(".", $m->docFileName);
759 #$_ext = end( $_split );
760 #if( false === $onlyimages || true === $onlyimages && in_array(strtolower($_ext), array('jpg','jpeg','png','gif','svg','tiff','bmp','webp') ) )
761 $res[] = ['id'=>$m->docId,'filename'=>$m->docFileName,'url'=>$this->getImage($m->docId)];
762 }
763 Helper::set_cache( $cache_key, $res, self::CACHE_TTL );;
764
765 if( true === $onlyimages ) {
766
767 $new = [];
768 foreach ($res as $imgs) {
769 if( self::is_image( $imgs['filename'] ) )
770 $new[] = $imgs;
771 }
772 return $new;
773 }
774
775 return $res;
776 }
777 return false;
778 }
779 return $cache;
780 }
781
782
783
784 /**
785 * Get Original Equipment Number
786 * @param mixed $article Use ArticleId or Article [Object]
787 * @return object
788 */
789 public function getArticleOEN( $article = null )
790 {
791 if( empty($article) )
792 return false;
793
794 if( !is_object($article) && !is_array($article) && is_numeric( $article ) ) {
795 $article = $this->getArticleData( $article );
796 }
797 $cache_key = 'article-oen:'.$article->directArticle->articleId;
798 $cache = Helper::check_cache( $cache_key );
799 if( !$cache ) {
800 // Find OE-Numbers
801 $oe = $article->oenNumbers->array;
802 if( is_array( $oe ) ) {
803 $data = [];
804 foreach ($oe as $n) {
805 $data[$n->brandName][] = $n->oeNumber;
806 }
807 return Helper::set_cache( $cache_key, $data, self::CACHE_TTL );
808 }
809 return false;
810 }
811 return $cache;
812
813 }
814
815 /**
816 * Search TecDoc for an Article
817 * @param string $query Search Query
818 * @param integer $brand Brand ID (Optional)
819 * @param integer $searchType Method of search (optional, defaults to 10)
820 * @return object
821 */
822 public function searchArticles( $query = null, $brand = null, $searchType = 10, $exact = false )
823 {
824 #var_dump( boolval($exact) );
825 #exit();
826 $searchType = array_key_exists($searchType, [0,1,2,3,4,5,7,10]) ? $searchType : 10; // see: getAvailableSearchMethods()
827 $query = explode( "/", $query );
828 $alfa = null;
829 if( count( $query ) == 2 ) {
830 $alfa = $query[0];
831 $query = $query[1];
832 } elseif( count( $query ) == 1 ) {
833 $query = $query[0];
834 } else {
835 $query = implode("", $query);
836 }
837 $args = [
838 'articleNumber'=>$query,
839 'numberType'=> $searchType,
840 ];
841 if( true === boolval($exact) )
842 $args['searchExact'] = true;
843
844 if( !empty($alfa) ) {
845 $args['genericArticleId'] = $alfa;
846
847 if( !is_numeric($alfa) )
848 $args['genericArticleId'] = $this->getArticleIdFromAlphaCode( $alfa );
849
850 }
851 if( !empty($brand) ) {
852 $args['brandId'] = is_numeric($brand) ? $brand : $this->getBrandIDfromName( $brand );
853 }
854
855# var_dump( $args );
856# exit();
857
858
859 $find = $this->request( 'getArticleDirectSearchAllNumbersWithState', $args);
860 return $find && is_array($find) ? $find : false;
861 }
862
863 public function getBrandIDfromName( $brand = null )
864 {
865 $all = $this->getAvailableBrands();
866 $best = false;
867 $cm = 0;
868 $brand = strtolower($brand);
869
870 foreach ($all as $b) {
871 $name = strtolower($b->brandName);
872 if( $brand == $name ) {
873 return $b->brandId; // If 100% match, just return
874 }
875
876 $sim = similar_text($brand, $name, $match);
877
878
879
880 if( $match >= $cm ) {
881 $cm = $match;
882
883 #echo $cm;
884 #var_dump( $b );
885 $best = $b->brandId;
886 }
887 $match = null;
888 }
889 return $cm > 69 ? $best : false;
890 }
891
892 public function getArticleIdFromAlphaCode( $code = null )
893 {
894 $DB = Helper::DB();
895
896 return 448;
897 }
898
899 public function get_category_from_code( $code = null )
900 {
901 $DB = Helper::DB();
902 $check = $DB->get_results('SELECT * FROM '.$DB->prefix.'tecdoc_alfacodes WHERE tecdocid='.$code);
903 $res = isset( $check[0] ) ? $check[0] : [];
904
905 return $res;
906
907 }
908
909 public function populate_alphacodes()
910 {
911 $DB = Helper::DB();
912 $check = $DB->get_results('SELECT COUNT(id) as total_rows FROM '.$DB->prefix.'tecdoc_alfacodes');
913 $tot = isset( $check[0]->total_rows ) ? $check[0]->total_rows : 0;
914
915 if( empty( $check ) || $tot == 0 ) {
916
917 $find = $this->request( 'getGenericArticles', [
918 'linkingTargetId' => 1677,
919 'linkingTargetType' =>'PO'
920 ]);
921 $find = $find && is_array($find) ? $find : false;
922
923
924 if( false !== $find ) {
925
926 #var_dump($find[0]);
927 foreach ($find as $ob) {
928 $DB->insert( $DB->prefix.'tecdoc_alfacodes', [
929 'alphacode'=>'',
930 'assemblygroup'=>$ob->assemblyGroup,
931 'designation'=>$ob->designation,
932 'masterdesignation'=>$ob->masterDesignation,
933 'usagedesignation'=>isset($ob->usageDesignation) ? $ob->usageDesignation : null,
934 'tecdocid'=>$ob->genericArticleId
935 ]);
936 #echo $ob->genericArticleId."<br/>";
937 }
938 }
939
940
941 } else {
942 echo 'Allready imported..';
943 }
944
945 }
946
947
948
949 /**
950 * List Available methods of searching TecDoc
951 * @return array
952 */
953 public function getAvailableSearchMethods()
954 {
955 return [
956 //'10' => 'Any',
957 '0' => 'Article Number' ,
958 '1' =>'OE Number',
959 '2' => 'Trade Number',
960 '3' => 'Comparable number',
961 '4' => 'Replacement number',
962 '5' => 'Replaced number',
963 '6' => 'EAN Number (barcode)'
964 ];
965 }
966
967 /**
968 * List categories
969 * @param integer $carID TecDoc Car ID ( Optional )
970 * @param boolean $childs Show expanded with all children
971 * @param integer $parent_id Show children of this ID
972 * @return object
973 */
974 public function getArticleCategories( $carID = null, $childs = true, $parent_id = null )
975 {
976 $args = [
977 'linked'=>true,
978 'linkingTargetType'=>(empty($carID) ? 'U' : 'P'), /* P = Passenger, O = Commercial, U = Universal */
979 'childNodes'=>$childs
980 ];
981 if( $carID ) {
982 $args['linkingTargetId'] = $carID;
983 }
984 if( $parent_id ) {
985 $args['parentNodeId'] = $parent_id;
986 }
987 $find = $this->request('getChildNodesAllLinkingTarget2', $args, true);
988
989 return $find;
990 }
991
992
993 /**
994 * Get All articles from manufactor
995 * @param integer $node_id Group Node ID
996 * @param integer $car_id Car ID (Optional)
997 * @return object
998 */
999 public function getArticlesFromManufactor( $node_id, $car_id = null, $brands = null )
1000 {
1001 $args = [
1002 'assemblyGroupNodeId'=>$node_id,
1003 'linkingTargetType'=>(empty($car_id) ? 'U' : 'P')
1004 ];
1005 if( $car_id ) {
1006 $args['linkingTargetId'] = $car_id;
1007 }
1008 if( $brands ) {
1009 $args['brandNo'] = ['array'=>array_keys($brands)];
1010
1011 }
1012
1013
1014 $find = $this->request('getGenericArticlesByManufacturer6', $args, true);
1015 #echo '<pre>';
1016 #echo json_encode( [ $this->request_params ], JSON_PRETTY_PRINT );
1017
1018 #var_dump( $find );
1019 #echo '</pre>';
1020 if( !is_array($find) && empty($find->data) )
1021 return null;
1022
1023 $data = [];
1024 foreach ($find as $art) {
1025
1026 $data[] = $this->getArticlesFromCategory( $node_id, $art->brandNo, $art->genericArticleId, $car_id );
1027 #echo '</pre><hr/>';
1028 }
1029
1030 return $data;
1031 }
1032
1033 /**
1034 * Get all articles from an Category?
1035 * @todo Write a better description for this method and what it actually does..
1036 * @todo 16.07.18: Note to self.. You are an useless a*hole ;) Thanks for nothing!!
1037 * @param integer $node_id Node ID
1038 * @param integer $brand_id Brand ID
1039 * @param integer $article_id Article ID
1040 * @param integer $car_id Car ID
1041 * @return object
1042 */
1043 private function getArticlesFromCategory( $node_id, $brand_id, $article_id, $car_id = null )
1044 {
1045 $args = [
1046 'assemblyGroupNodeId'=>$node_id,
1047 'brandNo'=>['array'=> (int) $brand_id],
1048 'genericArticleId'=>['array'=> (int) $article_id],
1049 'linkingTargetType'=>(empty($car_id) ? 'U' : 'P')
1050 ];
1051 if( $car_id ) {
1052 $args['linkingTargetId'] = $car_id;
1053 }
1054 $find = $this->request('getArticleIdsWithState', $args, true);
1055 return $find;
1056 }
1057
1058 /**
1059 * Get the parent ID
1060 * TecDoc does not provide ´ParentNodeId´ if the object has children
1061 * @param integer $node Current Node ID
1062 * @param integer $car Car ID
1063 * @return integer parentNodeId
1064 */
1065 public function getCategoryParent( $node = null, $car = null )
1066 {
1067 $all = $this->getArticleCategories( $car, true);
1068 #var_dump( $this->error );
1069 $ret = -1;
1070 foreach ($all as $o) {
1071 if( $o->assemblyGroupNodeId == $node && isset($o->parentNodeId) ) {
1072 $ret = $o->parentNodeId;
1073 continue;
1074 }
1075 }
1076 return $ret;
1077 }
1078
1079 /**
1080 * Get TecDOC Image URL
1081 * @param integer $id The Image ID
1082 * @param boolean $thumb Return thumbnail or full size image
1083 * @return string
1084 */
1085 public function getImage( $id, $thumb = false )
1086 {
1087 return $this->getDocumentOrImageUri( $id, $thumb );
1088 }
1089
1090 /**
1091 * Get TecDOC Document URL
1092 * @param integer $id The Document ID
1093 * @return string
1094 */
1095 public function getDocument( $id )
1096 {
1097 return $this->getDocumentOrImageUri( $id, false );
1098 }
1099
1100 /**
1101 * Get list of favorite cars
1102 * @deprecated 1.0.6 No longer used. Use getManufacturers'
1103 * @see getManufacturers()
1104 * @return array
1105 */
1106 public function favList()
1107 {
1108
1109 $list = [
1110 'ACURA',
1111 'ALFA ROMEO',
1112 'ALPINA',
1113 'AMC',
1114 'ASTON MARTIN',
1115 'AUDI',
1116 'AUSTIN',
1117 'BENTLEY',
1118 'BMW',
1119 'BUICK',
1120 'CADILLAC',
1121 'CHEVROLET',
1122 'CHRYSLER',
1123 'CITROËN',
1124 'DACIA',
1125 'DAEWOO',
1126 'DAF',
1127 'DAIHATSU',
1128 'DAIMLER',
1129 'DATSUN', // Finnes ikke....
1130 'DODGE',
1131 'EAGLE', // Finnes ikke....
1132 'FERRARI',
1133 'FIAT',
1134 'FORD',
1135 'FORD USA',
1136 'GLAS',
1137 'GMC',
1138 'HONDA',
1139 'HUMMER',
1140 'HYUNDAI',
1141 'INDIGO',
1142 'INFINITI',
1143 'INTERNATIONAL', // Finnes ikke....
1144 'ISUZU',
1145 'IVECO',
1146 'JAGUAR',
1147 'JEEP',
1148 'KIA',
1149 'LADA',
1150 'LAMBORGHINI',
1151 'LANCIA',
1152 'LAND ROVER',
1153 'LDV',
1154 'LEXUS',
1155 'LINCOLN',
1156 'LOTUS',
1157 'MASERATI',
1158 'MAYBACH',
1159 'MAZDA',
1160 'MCLAREN',
1161 'MERCEDES-BENZ',
1162 'MERCURY', // Finnes ikke....
1163 'MG',
1164 'MINI',
1165 'MITSUBISHI',
1166 'MORGAN',
1167 'MORRIS',
1168 'NISSAN',
1169 'NSU',
1170 'OLDSMOBILE',
1171 'OPEL',
1172 'PEUGEOT',
1173 'PIAGGIO',
1174 'PLYMOUTH',
1175 'PONTIAC',
1176 'PORSCHE',
1177 'PROTON',
1178 'RENAULT',
1179 'ROVER',
1180 'SAAB',
1181 'SEAT',
1182 'SKODA',
1183 'SMART',
1184 'SSANGYONG',
1185 'SUBARU',
1186 'SUZUKI',
1187 'TALBOT',
1188 'TESLA',
1189 'TOYOTA',
1190 'TRABANT',
1191 'TRIUMPH',
1192 'TVR',
1193 'VAUXHALL',
1194 'VOLVO',
1195 'VW',
1196 'YUGO' // Finnes ikke....
1197 ];
1198 $allManufactors = $this->getManufacturers();
1199 $new = [];
1200 foreach ($allManufactors as $manu) {
1201 $straight[$manu->manuId] = $manu->manuName;
1202
1203 if( in_array($manu->manuName, $list) ) {
1204 #echo $manu->manuId." => '".$manu->manuName."',\n";
1205 $new[$manu->manuId] = $manu->manuName;
1206 }
1207 }
1208 return $new;
1209
1210 }
1211
1212
1213 /**
1214 * Make and send an POST Request to tecDoc with default parameters
1215 * @access PRIVATE
1216 * @param string $method TecDoc Functionname for endpoints
1217 * @param array $params Paramenters to pass along to tecdoc
1218 * @return mixed Object or false if requests fails
1219 */
1220 private function send_request( $method = null, $params = array() )
1221 {
1222 $defaults = [
1223 "country" => self::LNG,
1224 "articleCountry" => self::LNG,
1225 "lang" => strtolower(self::LNG),
1226 "provider" => $this->provider,
1227 ];
1228
1229 $payload = json_encode( [ $method => array_merge($defaults, $params ) ] );
1230
1231
1232 $this->request_params = array_merge($defaults, $params );
1233
1234 $headers = ['content_type'=>'application/json','headers'=>['Content-Length: '.strlen($payload)]];
1235 $response = Helper::http_post( self::URI, $payload, $headers );
1236
1237 if( false == $response ) {
1238 $this->error = Helper::get_last_error();
1239 return false;
1240 }
1241
1242 $data = json_decode( $response );
1243
1244 //var_dump( $response );
1245 $this->current_response = $data;
1246 $this->current_status = $data->status;
1247
1248 if( $data->status == 200 ) {
1249
1250 if( isset( $data->data->array ) && is_array($data->data->array ) && !empty( $data->data->array ) )
1251 return $data->data->array;
1252 if( isset($data->data) && is_array( $data->data) )
1253 return $data->data;
1254
1255 return $data;
1256 } else {
1257 $this->error = $data->statusText;
1258 return false;
1259 }
1260 }
1261
1262 /**
1263 * Generate the TecDoc uri for images or documents
1264 * @access PRIVATE
1265 * @param integer $id Instance ID (docID or thumbDocId)
1266 * @param boolean $thumb Return thumbnail if this is an image
1267 * @return string
1268 */
1269 private function getDocumentOrImageUri( $id, $thumb=false)
1270 {
1271 return sprintf( self::ASSETS_URI . '/%s/%s/%d', $this->provider, $id, ($thumb ? '1' : '2') );
1272 }
1273
1274 /**
1275 * Check if path/url looks like a image
1276 * @access PUBLIC
1277 * @param string $nm The url or path
1278 * @return boolean
1279 */
1280 public static function is_image($nm)
1281 {
1282 $ext = array('jpg','jpeg','png','gif','svg','tiff','bmp','webp');
1283 $url = strtolower($nm);
1284 $urlExt = pathinfo($url, PATHINFO_EXTENSION);
1285 return in_array($urlExt, $ext) ? true : false;
1286 }
1287
1288 /**
1289 * Get an array of years in a range
1290 * @access PRIVATE
1291 * @param integer $start Range start
1292 * @param integer $stop Range stop
1293 * @return array
1294 */
1295 private function getYears($start,$stop)
1296 {
1297 $years = [];
1298 for( $i = $start; $i <= $stop; $i++ ) {
1299 $years[] = $i;
1300 }
1301 return $years;
1302 }
1303
1304 /**
1305 * Filter out just variations of the car name
1306 * @todo Change with regex?
1307 * @access PRIVATE
1308 * @param string $name Model Name
1309 * @return array
1310 */
1311 private function cleanVariantName( $name )
1312 {
1313 $split = explode("(", $name, 2);
1314
1315 if( isset($split[1]) ) {
1316 $list_variants = trim(rtrim($split[1], ")"));
1317 $variant = array($list_variants);
1318 if( strpos($list_variants, ",") !== false ) {
1319 $variant = explode(",", $list_variants);
1320 $variant=array_map('trim',$variant);
1321 }
1322 } else {
1323 $variant = array(trim($split[0]));
1324 }
1325 return $variant;
1326 }
1327 /**
1328 * Remove variant information from model name
1329 * @access PRIVATE
1330 * @param string $name Model Name
1331 * @return string
1332 */
1333 private function removeVariantName( $name )
1334 {
1335 $name = preg_replace('/\([^)]+\)/s', '', $name);
1336 return $name;
1337 }
1338
1339 /**
1340 * Parse the Motorcode data from TecDoc
1341 * @access PRIVATE
1342 * @param object $mk Motorcode object
1343 * @return mixed Array if multiple codes or String
1344 */
1345 private function parseMotorcodes( $mk = null )
1346 {
1347 if( !empty($mk) ) {
1348 if( is_array($mk->motorCodes->array) && count( $mk->motorCodes->array ) > 1 ) {
1349 $res = [];
1350 foreach ($mk->motorCodes->array as $mkk) {
1351 $res[] = $mkk->motorCode;
1352 }
1353 return $res;
1354 }
1355 return $mk->motorCodes->array[0]->motorCode;
1356 }
1357 }
1358 /**
1359 * Remove special characters from a string and replace with "normal"
1360 * @param string $text Text to check
1361 * @access PRIVATE
1362 * @return string
1363 */
1364 private function cleanString($text) {
1365 $utf8 = [
1366 '/[áàâãªä]/u' => 'a',
1367 '/[ÁÀÂÃÄ]/u' => 'A',
1368 '/[ÍÌÎÏ]/u' => 'I',
1369 '/[íìîï]/u' => 'i',
1370 '/[éèêë]/u' => 'e',
1371 '/[ÉÈÊË]/u' => 'E',
1372 '/[óòôõºö]/u' => 'o',
1373 '/[ÓÒÔÕÖ]/u' => 'O',
1374 '/[úùûü]/u' => 'u',
1375 '/[ÚÙÛÜ]/u' => 'U',
1376 '/ç/' => 'c',
1377 '/Ç/' => 'C',
1378 '/ñ/' => 'n',
1379 '/Ñ/' => 'N',
1380 '/–/' => '-', // UTF-8 hyphen to "normal" hyphen
1381 '/[’‘‹›‚]/u' => ' ', // Literally a single quote
1382 '/[“”«»„]/u' => ' ', // Double quote
1383 '/ /' => ' ', // nonbreaking space (equiv. to 0x160)
1384 ];
1385 return preg_replace(array_keys($utf8), array_values($utf8), $text);
1386 }
1387
1388 /**
1389 * Return any error
1390 * @return string
1391 */
1392 public function getError()
1393 {
1394 return $this->error;
1395 }
1396
1397 /**
1398 * Return last request_params for debug purposes
1399 * @return array
1400 */
1401 public function getParams()
1402 {
1403 return $this->request_params;
1404 }
1405
1406 public function getResponse()
1407 {
1408 return $this->current_response;
1409 }
1410
1411 public function getStatus()
1412 {
1413 return $this->current_status;
1414 }
1415 public function insert_to_car_db( $obj = null, $force = false )
1416 {
1417 global $wpdb;
1418 #$DB = Helper::DB();
1419 $DB = $wpdb;
1420
1421 if( empty($obj) || !is_object($obj) )
1422 return false;
1423
1424 $car = $obj;
1425 $id = $car->carId;
1426 $tbl = $DB->prefix."tecdoc_cars";
1427
1428 $check_db = $DB->get_results("SELECT * FROM $tbl WHERE car_id = '".$id."'");
1429
1430
1431
1432 $insert = [
1433 'time_created' => current_time('mysql',1),
1434 'car_id'=>$car->carId,
1435 'car_name'=>$car->manuName." ".rtrim($this->removeVariantName( $car->modelName ))." ".$car->typeName,
1436 'car_brand'=>$car->manuName,
1437 'car_modelname'=>rtrim($this->removeVariantName( $car->modelName )),
1438 'car_model'=>$car->modelName,
1439 'car_type'=>$car->typeName,
1440 'car_engine'=>(is_array($car->motorCode) ? implode(", ", $car->motorCode) : $car->motorCode),
1441 'car_fuel'=>$car->fuelType,
1442 'car_from'=>$this->filterProductionYears($car->yearOfConstrFrom, 'y')."/".$this->filterProductionYears($car->yearOfConstrFrom, 'm'),
1443 'car_to'=>$this->filterProductionYears($car->yearOfConstrTo, 'y')."/".$this->filterProductionYears($car->yearOfConstrTo, 'm')
1444 ];
1445
1446 $insert['car_to'] = $insert['car_to'] == '/' ? '' : $insert['car_to'];
1447
1448
1449 if($DB->num_rows >= 1 ) {
1450
1451 if( true === $force ) {
1452 $DB->update( $tbl, $insert, ['car_id'=>$id] );
1453 }
1454 } else {
1455 $do = $DB->insert( $tbl, $insert );
1456 }
1457
1458 }
1459
1460}
1461
1462
1463