PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/wp-lister-for-ebay/classes/model/ListingsModel.php

https://bitbucket.org/sanders_nick/my-maxi-skirt
PHP | 1074 lines | 706 code | 254 blank | 114 comment | 68 complexity | 856c493ed9def5538d5cc330dcb4d41a MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-1.0, GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * ListingsModel class
  4. *
  5. * responsible for managing listings and talking to ebay
  6. *
  7. */
  8. class ListingsModel extends WPL_Model {
  9. var $_session;
  10. var $_cs;
  11. function ListingsModel()
  12. {
  13. global $wpl_logger;
  14. $this->logger = &$wpl_logger;
  15. global $wpdb;
  16. $this->tablename = $wpdb->prefix . 'ebay_auctions';
  17. }
  18. function getPageItems( $current_page, $per_page ) {
  19. global $wpdb;
  20. $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'id'; //If no sort, default to title
  21. $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'desc'; //If no order, default to asc
  22. $offset = ( $current_page - 1 ) * $per_page;
  23. // filter listing_status
  24. $where_sql = '';
  25. $listing_status = ( isset($_REQUEST['listing_status']) ? $_REQUEST['listing_status'] : 'all');
  26. if ( $listing_status != 'all' ) {
  27. $where_sql = "WHERE status = '".$listing_status."'";
  28. }
  29. // filter search_query
  30. $search_query = ( isset($_REQUEST['s']) ? $_REQUEST['s'] : false);
  31. if ( $search_query ) {
  32. $where_sql = "WHERE auction_title LIKE '%".$search_query."%'";
  33. }
  34. // get items
  35. $items = $wpdb->get_results("
  36. SELECT *
  37. FROM $this->tablename
  38. $where_sql
  39. ORDER BY $orderby $order
  40. LIMIT $offset, $per_page
  41. ", ARRAY_A);
  42. // get total items count - if needed
  43. if ( ( $current_page == 1 ) && ( count( $items ) < $per_page ) ) {
  44. $this->total_items = count( $items );
  45. } else {
  46. $this->total_items = $wpdb->get_var("
  47. SELECT COUNT(*)
  48. FROM $this->tablename
  49. ORDER BY $orderby $order
  50. ");
  51. }
  52. return $items;
  53. }
  54. /* the following methods could go into another class, since they use wpdb instead of EbatNs_DatabaseProvider */
  55. function getAll() {
  56. global $wpdb;
  57. $items = $wpdb->get_results("
  58. SELECT *
  59. FROM $this->tablename
  60. ORDER BY id DESC
  61. ", ARRAY_A);
  62. return $items;
  63. }
  64. function getItem( $id ) {
  65. global $wpdb;
  66. $item = $wpdb->get_row("
  67. SELECT *
  68. FROM $this->tablename
  69. WHERE id = '$id'
  70. ", ARRAY_A);
  71. $item['profile_data'] = $this->decodeObject( $item['profile_data'], true );
  72. // $item['details'] = $this->decodeObject( $item['details'] );
  73. return $item;
  74. }
  75. function deleteItem( $id ) {
  76. global $wpdb;
  77. $wpdb->query("
  78. DELETE
  79. FROM $this->tablename
  80. WHERE id = '$id'
  81. ");
  82. }
  83. function getItemByEbayID( $id ) {
  84. global $wpdb;
  85. $item = $wpdb->get_row("
  86. SELECT *
  87. FROM $this->tablename
  88. WHERE ebay_id = '$id'
  89. ");
  90. if (!$item) return false;
  91. $item->profile_data = $this->decodeObject( $item->profile_data, true );
  92. $item->details = $this->decodeObject( $item->details );
  93. return $item;
  94. }
  95. function getTitleFromItemID( $id ) {
  96. global $wpdb;
  97. $item = $wpdb->get_var("
  98. SELECT auction_title
  99. FROM $this->tablename
  100. WHERE ebay_id = '$id'
  101. ");
  102. return $item;
  103. }
  104. function getEbayIDFromID( $id ) {
  105. global $wpdb;
  106. $item = $wpdb->get_var("
  107. SELECT ebay_id
  108. FROM $this->tablename
  109. WHERE id = '$id'
  110. ");
  111. return $item;
  112. }
  113. function getEbayIDFromPostID( $post_id ) {
  114. global $wpdb;
  115. $item = $wpdb->get_var("
  116. SELECT ebay_id
  117. FROM $this->tablename
  118. WHERE post_id = '$post_id'
  119. ");
  120. return $item;
  121. }
  122. function getStatus( $id ) {
  123. global $wpdb;
  124. $item = $wpdb->get_var("
  125. SELECT status
  126. FROM $this->tablename
  127. WHERE id = '$id'
  128. ");
  129. return $item;
  130. }
  131. function getStatusFromPostID( $post_id ) {
  132. global $wpdb;
  133. $item = $wpdb->get_var("
  134. SELECT status
  135. FROM $this->tablename
  136. WHERE post_id = '$post_id'
  137. ORDER BY id DESC
  138. ");
  139. return $item;
  140. }
  141. function getListingIDFromPostID( $post_id ) {
  142. global $wpdb;
  143. $item = $wpdb->get_var("
  144. SELECT id
  145. FROM $this->tablename
  146. WHERE post_id = '$post_id'
  147. ORDER BY id DESC
  148. ");
  149. return $item;
  150. }
  151. function getAllListingsFromPostID( $post_id ) {
  152. global $wpdb;
  153. $items = $wpdb->get_results("
  154. SELECT *
  155. FROM $this->tablename
  156. WHERE post_id = '$post_id'
  157. ORDER BY id DESC
  158. ");
  159. return $items;
  160. }
  161. function getViewItemURLFromPostID( $post_id ) {
  162. global $wpdb;
  163. $item = $wpdb->get_var("
  164. SELECT ViewItemURL
  165. FROM $this->tablename
  166. WHERE post_id = '$post_id'
  167. ORDER BY id DESC
  168. ");
  169. return $item;
  170. }
  171. function getStatusSummary() {
  172. global $wpdb;
  173. $result = $wpdb->get_results("
  174. SELECT status, count(*) as total
  175. FROM $this->tablename
  176. GROUP BY status
  177. ");
  178. $summary = new stdClass();
  179. // $summary->prepared = false;
  180. // $summary->changed = false;
  181. foreach ($result as $row) {
  182. $status = $row->status;
  183. $summary->$status = $row->total;
  184. }
  185. return $summary;
  186. }
  187. function listingUsesFixedPriceItem( $listing_item )
  188. {
  189. // regard auction_type by default
  190. $useFixedPriceItem = ( 'FixedPriceItem' == $listing_item['auction_type'] ) ? true : false;
  191. // but switch to AddItem if BestOffer is enabled
  192. $profile_details = $listing_item['profile_data']['details'];
  193. if ( @$profile_details['bestoffer_enabled'] == '1' ) $useFixedPriceItem = false;
  194. return $useFixedPriceItem;
  195. }
  196. function addItem( $id, $session )
  197. {
  198. // skip this item if item status not allowed
  199. $allowed_statuses = array( 'prepared', 'verified' );
  200. if ( ! $this->itemHasAllowedStatus( $id, $allowed_statuses ) ) return false;
  201. // build item
  202. $ibm = new ItemBuilderModel();
  203. $item = $ibm->buildItem( $id, $session );
  204. if ( ! $ibm->checkItem($item) ) return $ibm->result;
  205. // preparation - set up new ServiceProxy with given session
  206. $this->initServiceProxy($session);
  207. // switch to FixedPriceItem if product has variations
  208. $listing_item = $this->getItem( $id );
  209. // $useFixedPriceItem = ( ProductWrapper::hasVariations( $listing_item['post_id'] ) ) ? true : false;
  210. // $useFixedPriceItem = ( 'FixedPriceItem' == $listing_item['auction_type'] ) ? true : false;
  211. $this->logger->info( "Adding #$id: ".$item->Title );
  212. if ( $this->listingUsesFixedPriceItem( $listing_item ) ) {
  213. $req = new AddFixedPriceItemRequestType();
  214. $req->setItem($item);
  215. $this->logger->debug( "Request: ".print_r($req,1) );
  216. $res = $this->_cs->AddFixedPriceItem($req);
  217. } else {
  218. $req = new AddItemRequestType();
  219. $req->setItem($item);
  220. $this->logger->debug( "Request: ".print_r($req,1) );
  221. $res = $this->_cs->AddItem($req);
  222. }
  223. // handle response and check if successful
  224. if ( $this->handleResponse($res) ) {
  225. // save ebay ID and fees to db
  226. $listingFee = $this->getListingFeeFromResponse( $res );
  227. $data['ebay_id'] = $res->ItemID;
  228. $data['fees'] = $listingFee;
  229. $data['status'] = 'published';
  230. $this->updateListing( $id, $data );
  231. // get details like ViewItemURL from ebay automatically
  232. $this->updateItemDetails( $id, $session );
  233. $this->logger->info( "Item #$id sent to ebay, ItemID is ".$res->ItemID );
  234. } // call successful
  235. return $this->result;
  236. } // addItem()
  237. function relistItem( $id, $session )
  238. {
  239. // skip this item if item status not allowed
  240. $allowed_statuses = array( 'ended', 'sold' );
  241. if ( ! $this->itemHasAllowedStatus( $id, $allowed_statuses ) ) return false;
  242. // build item
  243. $ibm = new ItemBuilderModel();
  244. $item = $ibm->buildItem( $id, $session );
  245. if ( ! $ibm->checkItem($item) ) return $ibm->result;
  246. // preparation - set up new ServiceProxy with given session
  247. $this->initServiceProxy($session);
  248. // switch to FixedPriceItem if product has variations
  249. $listing_item = $this->getItem( $id );
  250. // $useFixedPriceItem = ( ProductWrapper::hasVariations( $listing_item['post_id'] ) ) ? true : false;
  251. // $useFixedPriceItem = ( 'FixedPriceItem' == $listing_item['auction_type'] ) ? true : false;
  252. // add old ItemID for relisting
  253. $item->setItemID( $listing_item['ebay_id'] );
  254. $this->logger->info( "Relisting #$id (ItemID ".$listing_item['ebay_id'].") - ".$item->Title );
  255. if ( $this->listingUsesFixedPriceItem( $listing_item ) ) {
  256. $req = new RelistFixedPriceItemRequestType();
  257. $req->setItem($item);
  258. $this->logger->debug( "Request: ".print_r($req,1) );
  259. $res = $this->_cs->RelistFixedPriceItem($req);
  260. } else {
  261. $req = new RelistItemRequestType();
  262. $req->setItem($item);
  263. $this->logger->debug( "Request: ".print_r($req,1) );
  264. $res = $this->_cs->RelistItem($req);
  265. }
  266. // handle response and check if successful
  267. if ( $this->handleResponse($res) ) {
  268. // save ebay ID and fees to db
  269. $listingFee = $this->getListingFeeFromResponse( $res );
  270. $data['ebay_id'] = $res->ItemID;
  271. $data['fees'] = $listingFee;
  272. $data['status'] = 'published';
  273. $this->updateListing( $id, $data );
  274. // get details like ViewItemURL from ebay automatically
  275. $this->updateItemDetails( $id, $session );
  276. $this->logger->info( "Item #$id relisted on ebay, NEW ItemID is ".$res->ItemID );
  277. } // call successful
  278. return $this->result;
  279. } // relistItem()
  280. function reviseItem( $id, $session )
  281. {
  282. // skip this item if item status not allowed
  283. $allowed_statuses = array( 'published', 'changed' );
  284. if ( ! $this->itemHasAllowedStatus( $id, $allowed_statuses ) ) return false;
  285. // check if product has variations
  286. $listing_item = $this->getItem( $id );
  287. // $useFixedPriceItem = ( ProductWrapper::hasVariations( $listing_item['post_id'] ) ) ? true : false;
  288. // $useFixedPriceItem = ( 'FixedPriceItem' == $listing_item['auction_type'] ) ? true : false;
  289. // build item
  290. $ibm = new ItemBuilderModel();
  291. $item = $ibm->buildItem( $id, $session );
  292. if ( ! $ibm->checkItem($item) ) return $ibm->result;
  293. // if quantity is zero, end item instead
  294. if ( ( $item->Quantity == 0 ) && ( ! $this->VariationsHaveStock ) ) {
  295. $this->logger->info( "Item #$id has no stock, switching to endItem()" );
  296. return $this->endItem( $id, $session );
  297. }
  298. // preparation - set up new ServiceProxy with given session
  299. $this->initServiceProxy($session);
  300. // set ItemID to revise
  301. $item->setItemID( $this->getEbayIDFromID($id) );
  302. $this->logger->info( "Revising #$id: ".$p['auction_title'] );
  303. // switch to FixedPriceItem if product has variations
  304. if ( $this->listingUsesFixedPriceItem( $listing_item ) ) {
  305. $req = new ReviseFixedPriceItemRequestType();
  306. $req->setItem($item);
  307. $this->logger->debug( "Request: ".print_r($req,1) );
  308. $res = $this->_cs->ReviseFixedPriceItem($req);
  309. } else {
  310. $req = new ReviseItemRequestType();
  311. $req->setItem($item);
  312. $this->logger->debug( "Request: ".print_r($req,1) );
  313. $res = $this->_cs->ReviseItem($req);
  314. }
  315. // handle response and check if successful
  316. if ( $this->handleResponse($res) ) {
  317. // save ebay ID and fees to db
  318. #$listingFee = $this->getListingFeeFromResponse( $res );
  319. #$data['ebay_id'] = $res->ItemID;
  320. #$data['fees'] = $listingFee;
  321. $data['status'] = 'published';
  322. $this->updateListing( $id, $data );
  323. // get details like ViewItemURL from ebay automatically
  324. #$this->updateItemDetails( $id, $session );
  325. $this->logger->info( "Item #$id was revised, ItemID is ".$res->ItemID );
  326. } // call successful
  327. return $this->result;
  328. } // reviseItem()
  329. function verifyAddItem( $id, $session )
  330. {
  331. // skip this item if item status not allowed
  332. $allowed_statuses = array( 'prepared', 'verified' );
  333. if ( ! $this->itemHasAllowedStatus( $id, $allowed_statuses ) ) return false;
  334. // build item
  335. $ibm = new ItemBuilderModel();
  336. $item = $ibm->buildItem( $id, $session );
  337. if ( ! $ibm->checkItem($item) ) return $ibm->result;
  338. // preparation - set up new ServiceProxy with given session
  339. $this->initServiceProxy($session);
  340. // switch to FixedPriceItem if product has variations
  341. $listing_item = $this->getItem( $id );
  342. // $useFixedPriceItem = ( ProductWrapper::hasVariations( $listing_item['post_id'] ) ) ? true : false;
  343. // $useFixedPriceItem = ( 'FixedPriceItem' == $listing_item['auction_type'] ) ? true : false;
  344. $this->logger->info( "Verifying #$id: ".$item->Title );
  345. if ( $this->listingUsesFixedPriceItem( $listing_item ) ) {
  346. $req = new VerifyAddFixedPriceItemRequestType();
  347. $req->setItem($item);
  348. $this->logger->debug( "Request: ".print_r($req,1) );
  349. $res = $this->_cs->VerifyAddFixedPriceItem($req);
  350. } else {
  351. $req = new VerifyAddItemRequestType();
  352. $req->setItem($item);
  353. $this->logger->debug( "Request: ".print_r($req,1) );
  354. $res = $this->_cs->VerifyAddItem($req);
  355. }
  356. // handle response and check if successful
  357. if ( $this->handleResponse($res) ) {
  358. // save listing fees to db
  359. $listingFee = $this->getListingFeeFromResponse( $res );
  360. // $data['ebay_id'] = $res->ItemID;
  361. $data['fees'] = $listingFee;
  362. $data['status'] = 'verified';
  363. $this->updateListing( $id, $data );
  364. $this->logger->info( "Item #$id verified with ebay, getAck(): ".$res->getAck() );
  365. } // call successful
  366. return $this->result;
  367. } // verifyAddItem()
  368. function endItem( $id, $session )
  369. {
  370. // skip this item if item status not allowed
  371. $allowed_statuses = array( 'published' );
  372. if ( ! $this->itemHasAllowedStatus( $id, $allowed_statuses ) ) return false;
  373. // preparation - set up new ServiceProxy with given session
  374. $this->initServiceProxy($session);
  375. // get eBay ID
  376. $item = $this->getItem( $id );
  377. $item_id = $item['ebay_id'];
  378. $req = new EndItemRequestType(); # ***
  379. $req->setItemID( $item_id );
  380. $req->setEndingReason('LostOrBroken');
  381. $this->logger->info( "calling EndItem($id) #$item_id " );
  382. $this->logger->debug( "Request: ".print_r($req,1) );
  383. $res = $this->_cs->EndItem($req); # ***
  384. $this->logger->info( "EndItem() Complete #$item_id" );
  385. $this->logger->debug( "Response: ".print_r($res,1) );
  386. // handle response and check if successful
  387. if ( $this->handleResponse($res) ) {
  388. // save ebay ID and fees to db
  389. $data['end_date'] = $res->EndTime;
  390. $data['status'] = 'ended';
  391. $this->updateListing( $id, $data );
  392. $this->logger->info( "Item #$id was ended manually. " );
  393. } // call successful
  394. return $this->result;
  395. } // endItem()
  396. function itemHasAllowedStatus( $id, $allowed_statuses )
  397. {
  398. $item = $this->getItem( $id );
  399. if ( in_array( $item['status'], $allowed_statuses ) ) {
  400. return true;
  401. } else {
  402. $this->logger->info("skipped item $id with status ".$item['status']);
  403. $this->logger->debug("allowed_statuses: ".print_r($allowed_statuses,1) );
  404. $this->showMessage( sprintf( 'Skipped %s item: %s', $item['status'], $item['auction_title'] ), false, true );
  405. return false;
  406. }
  407. } // itemHasAllowedStatus()
  408. function getListingFeeFromResponse( $res )
  409. {
  410. $fees = new FeesType();
  411. $fees = $res->GetFees();
  412. foreach ($fees->getFee() as $fee) {
  413. if ( $fee->GetName() == 'ListingFee' ) {
  414. $listingFee = $fee->GetFee()->getTypeValue();
  415. }
  416. $this->logger->debug( 'FeeName: '.$fee->GetName(). ' is '. $fee->GetFee()->getTypeValue().' '.$fee->GetFee()->getTypeAttribute('currencyID') );
  417. }
  418. return $listingFee;
  419. } // getListingFeeFromResponse()
  420. public function updateItemDetails( $id, $session ) {
  421. global $wpdb;
  422. // get item data
  423. $item = $this->getItem( $id );
  424. // preparation
  425. $this->initServiceProxy($session);
  426. $this->_cs->setHandler('ItemType', array(& $this, 'updateItemDetail'));
  427. // download the shipping data
  428. $req = new GetItemRequestType();
  429. $req->setItemID( $item['ebay_id'] );
  430. #$req->setDetailName( 'PaymentOptionDetails' );
  431. #$req->setActiveList( true );
  432. $res = $this->_cs->GetItem($req);
  433. // handle response and check if successful
  434. if ( $this->handleResponse($res) ) {
  435. $this->logger->info( "Item #$id was updated from eBay, ItemID is ".$res->ItemID );
  436. } // call successful
  437. return $this->result;
  438. }
  439. function updateItemDetail($type, & $Detail)
  440. {
  441. global $wpdb;
  442. //#type $Detail ItemType
  443. // map ItemType to DB columns
  444. $data = $this->mapItemDetailToDB( $Detail );
  445. $this->logger->debug('Detail: '.print_r($Detail,1) );
  446. $this->logger->debug('data: '.print_r($data,1) );
  447. $wpdb->update( $this->tablename, $data, array( 'ebay_id' => $Detail->ItemID ) );
  448. #$this->logger->info('sql: '.$wpdb->last_query );
  449. #$this->logger->info( mysql_error() );
  450. return true;
  451. }
  452. function mapItemDetailToDB( $Detail )
  453. {
  454. //#type $Detail ItemType
  455. $data['ebay_id'] = $Detail->ItemID;
  456. $data['auction_title'] = $Detail->Title;
  457. $data['auction_type'] = $Detail->ListingType;
  458. $data['listing_duration'] = $Detail->ListingDuration;
  459. $data['date_published'] = $Detail->ListingDetails->StartTime;
  460. $data['end_date'] = $Detail->ListingDetails->EndTime;
  461. $data['price'] = $Detail->SellingStatus->CurrentPrice->value;
  462. $data['quantity_sold'] = $Detail->SellingStatus->QuantitySold;
  463. $data['quantity'] = $Detail->Quantity;
  464. $data['ViewItemURL'] = $Detail->ListingDetails->ViewItemURL;
  465. $data['GalleryURL'] = $Detail->PictureDetails->GalleryURL;
  466. // if this item has variations, we don't update quantity
  467. if ( count( @$Detail->Variations->Variation ) > 0 ) {
  468. unset( $data['quantity'] );
  469. $this->logger->info('skip quantity for variation #'.$Detail->ItemID );
  470. }
  471. // set status to ended if end_date is in the past
  472. if ( time() > mysql2date('U', $data['end_date']) ) {
  473. $data['status'] = 'ended';
  474. } else {
  475. $data['status'] = 'published';
  476. }
  477. $data['details'] = $this->encodeObject( $Detail );
  478. return $data;
  479. }
  480. public function updateListing( $id, $data ) {
  481. global $wpdb;
  482. // update
  483. $wpdb->update( $this->tablename, $data, array( 'id' => $id ) );
  484. #$this->logger->info('sql: '.$wpdb->last_query );
  485. #$this->logger->info( mysql_error() );
  486. }
  487. public function updateEndedListings( $sm = false ) {
  488. global $wpdb;
  489. $items = $this->getAllPastEndDate();
  490. foreach ($items as $item) {
  491. $wpdb->update( $this->tablename, array( 'status' => 'ended' ), array( 'id' => $item['id'] ) );
  492. }
  493. #$this->logger->info('sql: '.$wpdb->last_query );
  494. #$this->logger->info( mysql_error() );
  495. }
  496. function getAllSelected() {
  497. global $wpdb;
  498. $items = $wpdb->get_results("
  499. SELECT *
  500. FROM $this->tablename
  501. WHERE status = 'selected'
  502. ORDER BY id DESC
  503. ", ARRAY_A);
  504. return $items;
  505. }
  506. function getAllPrepared() {
  507. global $wpdb;
  508. $items = $wpdb->get_results("
  509. SELECT *
  510. FROM $this->tablename
  511. WHERE status = 'prepared'
  512. ORDER BY id DESC
  513. ", ARRAY_A);
  514. return $items;
  515. }
  516. function getAllVerified() {
  517. global $wpdb;
  518. $items = $wpdb->get_results("
  519. SELECT *
  520. FROM $this->tablename
  521. WHERE status = 'verified'
  522. ORDER BY id DESC
  523. ", ARRAY_A);
  524. return $items;
  525. }
  526. function getAllChanged() {
  527. global $wpdb;
  528. $items = $wpdb->get_results("
  529. SELECT *
  530. FROM $this->tablename
  531. WHERE status = 'changed'
  532. ORDER BY id DESC
  533. ", ARRAY_A);
  534. return $items;
  535. }
  536. function getAllPublished() {
  537. global $wpdb;
  538. $items = $wpdb->get_results("
  539. SELECT *
  540. FROM $this->tablename
  541. WHERE status = 'published'
  542. OR status = 'changed'
  543. ORDER BY id DESC
  544. ", ARRAY_A);
  545. return $items;
  546. }
  547. function getAllPreparedWithProfile( $profile_id ) {
  548. global $wpdb;
  549. $items = $wpdb->get_results("
  550. SELECT *
  551. FROM $this->tablename
  552. WHERE status = 'prepared'
  553. AND profile_id = '$profile_id'
  554. ORDER BY id DESC
  555. ", ARRAY_A);
  556. return $items;
  557. }
  558. function getAllVerifiedWithProfile( $profile_id ) {
  559. global $wpdb;
  560. $items = $wpdb->get_results("
  561. SELECT *
  562. FROM $this->tablename
  563. WHERE status = 'verified'
  564. AND profile_id = '$profile_id'
  565. ORDER BY id DESC
  566. ", ARRAY_A);
  567. return $items;
  568. }
  569. function getAllPublishedWithProfile( $profile_id ) {
  570. global $wpdb;
  571. $items = $wpdb->get_results("
  572. SELECT *
  573. FROM $this->tablename
  574. WHERE ( status = 'published' OR status = 'changed' )
  575. AND profile_id = '$profile_id'
  576. ORDER BY id DESC
  577. ", ARRAY_A);
  578. return $items;
  579. }
  580. function getAllPreparedWithTemplate( $template ) {
  581. global $wpdb;
  582. $items = $wpdb->get_results("
  583. SELECT *
  584. FROM $this->tablename
  585. WHERE status = 'prepared'
  586. AND template LIKE '%$template'
  587. ORDER BY id DESC
  588. ", ARRAY_A);
  589. return $items;
  590. }
  591. function getAllVerifiedWithTemplate( $template ) {
  592. global $wpdb;
  593. $items = $wpdb->get_results("
  594. SELECT *
  595. FROM $this->tablename
  596. WHERE status = 'verified'
  597. AND template LIKE '%$template'
  598. ORDER BY id DESC
  599. ", ARRAY_A);
  600. return $items;
  601. }
  602. function getAllPublishedWithTemplate( $template ) {
  603. global $wpdb;
  604. $items = $wpdb->get_results("
  605. SELECT *
  606. FROM $this->tablename
  607. WHERE ( status = 'published' OR status = 'changed' )
  608. AND template LIKE '%$template'
  609. ORDER BY id DESC
  610. ", ARRAY_A);
  611. return $items;
  612. }
  613. function getAllPastEndDate() {
  614. global $wpdb;
  615. $items = $wpdb->get_results("
  616. SELECT id
  617. FROM $this->tablename
  618. WHERE NOT status = 'ended'
  619. AND NOT listing_duration = 'GTC'
  620. AND end_date < NOW()
  621. ORDER BY id DESC
  622. ", ARRAY_A);
  623. return $items;
  624. }
  625. function getAllDuplicateProducts() {
  626. global $wpdb;
  627. $items = $wpdb->get_results("
  628. SELECT post_id, COUNT(*) c
  629. FROM $this->tablename
  630. GROUP BY post_id
  631. HAVING c > 1
  632. ", OBJECT_K);
  633. if ( ! empty($items) ) {
  634. foreach ($items as &$item) {
  635. $listings = $this->getAllListingsFromPostID( $item->post_id );
  636. $item->listings = $listings;
  637. }
  638. }
  639. return $items;
  640. }
  641. function getRawPostExcerpt( $post_id ) {
  642. global $wpdb;
  643. $excerpt = $wpdb->get_var("
  644. SELECT post_excerpt
  645. FROM {$wpdb->prefix}posts
  646. WHERE ID = $post_id
  647. ");
  648. return $excerpt;
  649. }
  650. public function selectedProducts() {
  651. global $wpdb;
  652. $items = $wpdb->get_results("
  653. SELECT *
  654. FROM $this->tablename
  655. WHERE status = 'selected'
  656. ORDER BY id DESC
  657. ", ARRAY_A);
  658. return $items;
  659. }
  660. public function setListingQuantity( $post_id, $quantity ) {
  661. global $wpdb;
  662. $wpdb->update( $this->tablename, array( 'quantity' => $quantity ), array( 'post_id' => $post_id ) );
  663. // echo $wpdb->last_query;
  664. // echo mysql_error();
  665. }
  666. public function markItemAsModified( $post_id ) {
  667. global $wpdb;
  668. // set published items to changed
  669. $wpdb->update( $this->tablename, array( 'status' => 'changed' ), array( 'status' => 'published', 'post_id' => $post_id ) );
  670. // set verified items to prepared
  671. $wpdb->update( $this->tablename, array( 'status' => 'prepared' ), array( 'status' => 'verified', 'post_id' => $post_id ) );
  672. }
  673. public function reSelectListings( $ids ) {
  674. global $wpdb;
  675. foreach( $ids as $id ) {
  676. $wpdb->update( $this->tablename, array( 'status' => 'selected' ), array( 'id' => $id ) );
  677. }
  678. }
  679. public function prepareListings( $ids ) {
  680. foreach( $ids as $id ) {
  681. $this->prepareProductForListing( $id );
  682. }
  683. }
  684. public function prepareProductForListing( $post_id, $post_content = false, $post_title = false ) {
  685. global $wpdb;
  686. // get wp post record
  687. $post = get_post( $post_id );
  688. // gather product data
  689. $data['post_id'] = $post_id;
  690. $data['auction_title'] = $post_title ? $post_title : $post->post_title;
  691. $data['post_content'] = $post_content ? $post_content : $post->post_content;
  692. $data['price'] = ProductWrapper::getPrice( $post_id );
  693. $data['status'] = 'selected';
  694. $this->logger->info('insert new auction '.$post_id.' - title: '.$data['auction_title']);
  695. $this->logger->debug( print_r($post,1) );
  696. // insert in auctions table
  697. $wpdb->insert( $this->tablename, $data );
  698. $this->logger->debug('sql: '.$wpdb->last_query );
  699. $this->logger->debug( mysql_error() );
  700. return $wpdb->insert_id;
  701. }
  702. function applyProfilePrice( $product_price, $profile_price ) {
  703. $this->logger->debug('applyProfilePrice(): '.$product_price.' - '.$profile_price );
  704. // remove all spaces from profile setting
  705. $profile_price = str_replace( ' ','', trim($profile_price) );
  706. // return product price if profile is empty
  707. if ( $profile_price == '' ) return $product_price;
  708. // handle percent
  709. if ( preg_match('/\%/',$profile_price) ) {
  710. $this->logger->debug('percent mode');
  711. // parse percent syntax
  712. if ( preg_match('/([\+\-]?)([0-9\.]+)(\%)/',$profile_price, $matches) ) {
  713. $this->logger->debug('matches:' . print_r($matches,1) );
  714. $modifier = $matches[1];
  715. $value = $matches[2];
  716. if ($modifier == '+') {
  717. return $product_price + ( $product_price * $value/100 );
  718. } elseif ($modifier == '-') {
  719. return $product_price - ( $product_price * $value/100 );
  720. } else {
  721. return ( $product_price * $value/100 );
  722. }
  723. } else {
  724. // no valid syntax
  725. return $product_price;
  726. }
  727. } else {
  728. $this->logger->debug('value mode');
  729. // parse value syntax
  730. if ( preg_match('/([\+\-]?)([0-9\.]+)/',$profile_price, $matches) ) {
  731. $this->logger->debug('matches:' . print_r($matches,1) );
  732. $modifier = $matches[1];
  733. $value = $matches[2];
  734. if ($modifier == '+') {
  735. return $product_price + $value;
  736. } elseif ($modifier == '-') {
  737. return $product_price - $value;
  738. } else {
  739. return $value;
  740. }
  741. } else {
  742. // no valid syntax
  743. return $product_price;
  744. }
  745. }
  746. }
  747. public function applyProfileToItem( $profile, $item, $update_title = true ) {
  748. global $wpdb;
  749. // get item data
  750. $id = $item['id'];
  751. $post_id = $item['post_id'];
  752. $status = $this->getStatus( $id );
  753. $ebay_id = $this->getEbayIDFromID( $id );
  754. $post_title = get_the_title( $item['post_id'] );
  755. // skip ended auctions
  756. if ( $status == 'ended' ) return;
  757. // gather profile data
  758. $data = array();
  759. $data['profile_id'] = $profile['profile_id'];
  760. $data['auction_type'] = $profile['type'];
  761. $data['listing_duration'] = $profile['listing_duration'];
  762. $data['template'] = $profile['details']['template'];
  763. $data['quantity'] = $profile['details']['quantity'];
  764. $data['date_created'] = date( 'Y-m-d H:i:s' );
  765. $data['profile_data'] = $this->encodeObject( $profile );
  766. // add prefix and suffix to product title
  767. if ( $update_title ) {
  768. // append space to prefix, prepend space to suffix
  769. // TODO: make this an option
  770. $title_prefix = trim( $profile['details']['title_prefix'] ) . ' ';
  771. $title_suffix = ' ' . trim( $profile['details']['title_suffix'] );
  772. $data['auction_title'] = trim( $title_prefix . $post_title . $title_suffix );
  773. }
  774. // process attribute shortcodes in title - like [[attribute_Brand]]
  775. $templatesModel = new TemplatesModel();
  776. $data['auction_title'] = $templatesModel->processAttributeShortcodes( $item['post_id'], $data['auction_title'] );
  777. $this->logger->info('processAttributeShortcodes('.$item['post_id'].')');
  778. $this->logger->info('auction_title: '.$data['auction_title'].'');
  779. // apply profile price
  780. $data['price'] = ProductWrapper::getPrice( $post_id );
  781. $data['price'] = $this->applyProfilePrice( $data['price'], $profile['details']['start_price'] );
  782. // fetch product stock if no quantity set in profile
  783. if ( intval( $data['quantity'] ) == 0 ) {
  784. $data['quantity'] = ProductWrapper::getStock( $post_id );
  785. }
  786. // default new status is 'prepared'
  787. $data['status'] = 'prepared';
  788. // except for already published items where it is 'changed'
  789. if ( intval($ebay_id) > 0 ) $data['status'] = 'changed';
  790. // update auctions table
  791. $wpdb->update( $this->tablename, $data, array( 'id' => $id ) );
  792. }
  793. public function applyProfileToItems( $profile, $items, $update_title = true ) {
  794. // apply profile to all items
  795. foreach( $items as $item ) {
  796. $this->applyProfileToItem( $profile, $item, $update_title );
  797. }
  798. return $items;
  799. }
  800. public function applyProfileToNewListings( $profile, $items = false, $update_title = true ) {
  801. // get selected items - if no items provided
  802. if (!$items) $items = $this->getAllSelected();
  803. $items = $this->applyProfileToItems( $profile, $items, $update_title );
  804. return $items;
  805. }
  806. public function reapplyProfileToItem( $id ) {
  807. // get item
  808. $item = $this->getItem( $id );
  809. // get profile
  810. $profilesModel = new ProfilesModel();
  811. $profile = $profilesModel->getItem( $item['profile_id'] );
  812. // re-apply profile
  813. $this->applyProfileToItem( $profile, $item );
  814. }
  815. public function reapplyProfileToItems( $ids ) {
  816. foreach( $ids as $id ) {
  817. $this->reapplyProfileToItem( $id );
  818. }
  819. }
  820. }