| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | namespace bhr\Includes; |
|---|
| 4 | |
|---|
| 5 | use bhr\Admin\Entity\Configuration; |
|---|
| 6 | use Error; |
|---|
| 7 | use Exception; |
|---|
| 8 | use SALESmanago\Model\Collections\Api\V3\ProductsCollection; |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | trait Helper { |
|---|
| 12 | |
|---|
| 13 | /** |
|---|
| 14 | * @param $input - array or string with commas |
|---|
| 15 | * @param bool $returnString - true to receive string, false for array |
|---|
| 16 | * @param false $removeInnerSpaces - spaces within items will be replaced with underscore |
|---|
| 17 | * @param false $toUpperCase |
|---|
| 18 | * @param string $separator - use separator different from comma |
|---|
| 19 | * @param int $maxLength - maximum length per value |
|---|
| 20 | * |
|---|
| 21 | * @return array|string |
|---|
| 22 | */ |
|---|
| 23 | public static function clearCSVInput( |
|---|
| 24 | $input, |
|---|
| 25 | $returnString = true, |
|---|
| 26 | $removeInnerSpaces = false, |
|---|
| 27 | $toUpperCase = false, |
|---|
| 28 | $separator = ',', |
|---|
| 29 | $maxLength = 255 |
|---|
| 30 | ) { |
|---|
| 31 | if ( empty( $input ) ) { |
|---|
| 32 | return $returnString ? '' : array(); |
|---|
| 33 | } |
|---|
| 34 | if ( is_string( $input ) && ! is_array( $input ) ) { |
|---|
| 35 | $inputArray = explode( ',', $input ); |
|---|
| 36 | } else { |
|---|
| 37 | $inputArray = $input; |
|---|
| 38 | } |
|---|
| 39 | $output = array(); |
|---|
| 40 | foreach ( $inputArray as $item ) { |
|---|
| 41 | if ( trim( $item ) ) { |
|---|
| 42 | $outItem = $toUpperCase |
|---|
| 43 | ? strtoupper( trim( $item ) ) |
|---|
| 44 | : trim( $item ); |
|---|
| 45 | $outItem = $removeInnerSpaces |
|---|
| 46 | ? str_replace( ' ', '_', $outItem ) |
|---|
| 47 | : $outItem; |
|---|
| 48 | $output[] = substr( $outItem, 0, $maxLength ); |
|---|
| 49 | } |
|---|
| 50 | } |
|---|
| 51 | |
|---|
| 52 | return $returnString |
|---|
| 53 | ? implode( $separator, $output ) |
|---|
| 54 | : $output; |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | /** |
|---|
| 58 | * @return string |
|---|
| 59 | */ |
|---|
| 60 | public static function getUserLocale() { |
|---|
| 61 | if ( function_exists( 'get_user_locale' ) ) { |
|---|
| 62 | return get_user_locale(); |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | return ''; |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | /** |
|---|
| 69 | * @return string |
|---|
| 70 | */ |
|---|
| 71 | public static function getLocation() { |
|---|
| 72 | try { |
|---|
| 73 | $shopLocation = null; |
|---|
| 74 | if ( function_exists( 'wc_get_page_id' ) ) { |
|---|
| 75 | $shopLocation = ( get_permalink( wc_get_page_id( 'shop' ) ) == - 1 ) |
|---|
| 76 | ? get_home_url() |
|---|
| 77 | : get_permalink( wc_get_page_id( 'shop' ) ); |
|---|
| 78 | } |
|---|
| 79 | if ( empty( $shopLocation ) ) { |
|---|
| 80 | $shopLocation = $_SERVER['SERVER_NAME']; |
|---|
| 81 | } |
|---|
| 82 | |
|---|
| 83 | return GlobalConstant::LOCATION_PREFIX . md5( $shopLocation ); |
|---|
| 84 | } catch ( Error $e ) { |
|---|
| 85 | error_log( $e->getMessage() ); |
|---|
| 86 | |
|---|
| 87 | return GlobalConstant::LOCATION_PREFIX . md5( strval( rand( 1, 100 ) ) ); |
|---|
| 88 | } |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | /** |
|---|
| 92 | * @return string |
|---|
| 93 | */ |
|---|
| 94 | public static function getLanguage( $lang ) { |
|---|
| 95 | return $lang === 'browser' |
|---|
| 96 | ? substr( $_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2 ) |
|---|
| 97 | : substr( static::getUserLocale(), 0, 2 ); |
|---|
| 98 | } |
|---|
| 99 | |
|---|
| 100 | /** |
|---|
| 101 | * @param $param |
|---|
| 102 | * |
|---|
| 103 | * @return false|\WC_Product|null |
|---|
| 104 | */ |
|---|
| 105 | public static function wcGetProduct( $param ) { |
|---|
| 106 | return wc_get_product( $param ); |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | /** |
|---|
| 110 | * @param $hook_name |
|---|
| 111 | * @param $callback |
|---|
| 112 | * @param int $priority |
|---|
| 113 | * @param int $accepted_args |
|---|
| 114 | */ |
|---|
| 115 | public static function addAction( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) { |
|---|
| 116 | add_action( $hook_name, $callback, $priority, $accepted_args ); |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | /** |
|---|
| 120 | * @param $plugin |
|---|
| 121 | * @param $deprecated |
|---|
| 122 | * @param $path |
|---|
| 123 | */ |
|---|
| 124 | public static function loadPluginTextDomain( $plugin, $deprecated, $path ) { |
|---|
| 125 | if ( function_exists( 'load_plugin_textdomain' ) ) { |
|---|
| 126 | load_plugin_textdomain( $plugin, $deprecated, $path ); |
|---|
| 127 | } |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | /** |
|---|
| 131 | * @param $param |
|---|
| 132 | * |
|---|
| 133 | * @return bool|\WC_Order|\WC_Order_Refund |
|---|
| 134 | */ |
|---|
| 135 | public static function wcGetOrder( $param ) { |
|---|
| 136 | return wc_get_order( $param ); |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | /** |
|---|
| 140 | * @return \WooCommerce |
|---|
| 141 | */ |
|---|
| 142 | public static function wc() { |
|---|
| 143 | return WC(); |
|---|
| 144 | } |
|---|
| 145 | |
|---|
| 146 | /** |
|---|
| 147 | * @param $orderId |
|---|
| 148 | * @param $productIdentifierType |
|---|
| 149 | * |
|---|
| 150 | * @return array |
|---|
| 151 | */ |
|---|
| 152 | public static function getProductsFromOrder( $orderId, $productIdentifierType ) { |
|---|
| 153 | /* Products */ |
|---|
| 154 | $order = self::wcGetOrder( $orderId ); |
|---|
| 155 | $ids = array(); |
|---|
| 156 | $variantIds = array(); |
|---|
| 157 | $names = array(); |
|---|
| 158 | $quantities = array(); |
|---|
| 159 | $skus = array(); |
|---|
| 160 | $smProductArray = array(); |
|---|
| 161 | |
|---|
| 162 | foreach ( $order->get_items() as $item_id => $item ) { |
|---|
| 163 | $WcProduct = Helper::wcGetProduct( $item['variation_id'] ) |
|---|
| 164 | ? Helper::wcGetProduct( $item['variation_id'] ) |
|---|
| 165 | : Helper::wcGetProduct( $item['product_id'] ); |
|---|
| 166 | if ( $WcProduct ) { |
|---|
| 167 | $smProductArray[] = self::getSmEventDetailsFromWcProduct( $WcProduct ); |
|---|
| 168 | } |
|---|
| 169 | $quantities[] = $item->get_quantity(); |
|---|
| 170 | } |
|---|
| 171 | |
|---|
| 172 | foreach ( $smProductArray as $SmProduct ) { |
|---|
| 173 | $ids[] = $SmProduct->getId(); |
|---|
| 174 | $variantIds[] = $SmProduct->getVariantId(); |
|---|
| 175 | $skus[] = $SmProduct->getSku(); |
|---|
| 176 | $names[] = $SmProduct->getName(); |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | /* Shipping */ |
|---|
| 180 | $shippingMethodNames = array(); |
|---|
| 181 | |
|---|
| 182 | foreach ( $order->get_items( 'shipping' ) as $item_id => $item ) { |
|---|
| 183 | $shippingMethodNames[] = $item->get_method_title(); |
|---|
| 184 | } |
|---|
| 185 | $shippingMethodName = implode( ',', $shippingMethodNames ); |
|---|
| 186 | |
|---|
| 187 | $products = array( |
|---|
| 188 | 'description' => $order->get_payment_method(), |
|---|
| 189 | 'value' => $order->get_total(), |
|---|
| 190 | 'detail1' => implode( ',', $names ), |
|---|
| 191 | 'detail2' => $order->get_order_key(), |
|---|
| 192 | 'detail3' => implode( '/', $quantities ), |
|---|
| 193 | 'detail4' => $order->get_customer_note(), |
|---|
| 194 | 'detail5' => $shippingMethodName, |
|---|
| 195 | 'externalId' => $order->get_id(), |
|---|
| 196 | ); |
|---|
| 197 | |
|---|
| 198 | $products += self::generateProductsDetailsByIdentifierType( |
|---|
| 199 | $productIdentifierType, |
|---|
| 200 | $ids, |
|---|
| 201 | $variantIds, |
|---|
| 202 | $skus |
|---|
| 203 | ); |
|---|
| 204 | |
|---|
| 205 | return $products; |
|---|
| 206 | } |
|---|
| 207 | |
|---|
| 208 | /** |
|---|
| 209 | * @param $productIdentifierType |
|---|
| 210 | * @param $ids |
|---|
| 211 | * @param $skus |
|---|
| 212 | * @param $variantIds |
|---|
| 213 | * |
|---|
| 214 | * @return array |
|---|
| 215 | */ |
|---|
| 216 | public static function generateProductsDetailsByIdentifierType( |
|---|
| 217 | $productIdentifierType = '', |
|---|
| 218 | $ids = array(), |
|---|
| 219 | $variantIds = array(), |
|---|
| 220 | $skus = array() |
|---|
| 221 | ) { |
|---|
| 222 | switch ( $productIdentifierType ) { |
|---|
| 223 | case 'sku': |
|---|
| 224 | $product['products'] = implode( ',', $skus ); |
|---|
| 225 | $product['detail6'] = implode( ',', $ids ); |
|---|
| 226 | $product['detail7'] = implode( ',', $variantIds ); |
|---|
| 227 | break; |
|---|
| 228 | |
|---|
| 229 | case 'variant Id': |
|---|
| 230 | $product['products'] = implode( ',', $variantIds ); |
|---|
| 231 | $product['detail6'] = implode( ',', $ids ); |
|---|
| 232 | $product['detail7'] = implode( ',', $skus ); |
|---|
| 233 | break; |
|---|
| 234 | |
|---|
| 235 | default: |
|---|
| 236 | $product['products'] = implode( ',', $ids ); |
|---|
| 237 | $product['detail6'] = implode( ',', $skus ); |
|---|
| 238 | $product['detail7'] = implode( ',', $variantIds ); |
|---|
| 239 | break; |
|---|
| 240 | } |
|---|
| 241 | |
|---|
| 242 | return $product; |
|---|
| 243 | } |
|---|
| 244 | |
|---|
| 245 | /** |
|---|
| 246 | * @param $WcProduct |
|---|
| 247 | * |
|---|
| 248 | * @return SmProduct |
|---|
| 249 | */ |
|---|
| 250 | public static function getSmEventDetailsFromWcProduct( $WcProduct ) { |
|---|
| 251 | $SmProduct = new SmProduct(); |
|---|
| 252 | |
|---|
| 253 | /* Simple products have no parent */ |
|---|
| 254 | $WcProduct->get_parent_id() !== 0 |
|---|
| 255 | ? $SmProduct->setId( $WcProduct->get_parent_id() ) |
|---|
| 256 | : $SmProduct->setId( $WcProduct->get_id() ); |
|---|
| 257 | |
|---|
| 258 | $SmProduct->setVariantId( $WcProduct->get_id() ) |
|---|
| 259 | ->setSku( $WcProduct->get_sku() ) |
|---|
| 260 | ->setUnitPrice( $WcProduct->get_price() ) |
|---|
| 261 | ->setName( $WcProduct->get_name() ); |
|---|
| 262 | |
|---|
| 263 | return $SmProduct; |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| 266 | /** |
|---|
| 267 | * @param $postId |
|---|
| 268 | * @param $key |
|---|
| 269 | * @param $single |
|---|
| 270 | * |
|---|
| 271 | * @return mixed |
|---|
| 272 | */ |
|---|
| 273 | public static function getPostMetaData( $postId, $key, $single ) { |
|---|
| 274 | return get_post_meta( $postId, $key, $single ); |
|---|
| 275 | } |
|---|
| 276 | |
|---|
| 277 | /** |
|---|
| 278 | * @param $type |
|---|
| 279 | * @param $arg |
|---|
| 280 | * |
|---|
| 281 | * @return false|\WP_User |
|---|
| 282 | */ |
|---|
| 283 | public static function getUserBy( $type, $arg ) { |
|---|
| 284 | return get_user_by( $type, $arg ); |
|---|
| 285 | } |
|---|
| 286 | |
|---|
| 287 | /** |
|---|
| 288 | * Verify if endpoint starts with https |
|---|
| 289 | * |
|---|
| 290 | * @param string $endpoint |
|---|
| 291 | * |
|---|
| 292 | * @return false|int |
|---|
| 293 | */ |
|---|
| 294 | public static function checkEndpointForHTTPS( $endpoint ) { |
|---|
| 295 | return preg_match( '/^(https:\/\/)+/', $endpoint ); |
|---|
| 296 | } |
|---|
| 297 | |
|---|
| 298 | /** |
|---|
| 299 | * Make sure that salesmanago plugin is loaded last so that woocommerce functions can be used |
|---|
| 300 | * |
|---|
| 301 | * @return void |
|---|
| 302 | */ |
|---|
| 303 | public static function loadSMPluginLast() { |
|---|
| 304 | $SMPlugin = "salesmanago/salesmanago.php"; |
|---|
| 305 | $activePlugins = get_option( 'active_plugins' ); |
|---|
| 306 | $thisPluginKey = array_search( $SMPlugin, $activePlugins ); |
|---|
| 307 | |
|---|
| 308 | if ( in_array( $SMPlugin, $activePlugins ) && end( $activePlugins ) !== $SMPlugin ) { |
|---|
| 309 | array_splice( $activePlugins, $thisPluginKey, 1 ); |
|---|
| 310 | array_push( $activePlugins, $SMPlugin ); |
|---|
| 311 | update_option( 'active_plugins', $activePlugins ); |
|---|
| 312 | } |
|---|
| 313 | } |
|---|
| 314 | |
|---|
| 315 | /** |
|---|
| 316 | * Helper function to get image url |
|---|
| 317 | * |
|---|
| 318 | * @param $image_tag string |
|---|
| 319 | * |
|---|
| 320 | * @return string|false |
|---|
| 321 | */ |
|---|
| 322 | public static function getImageUrl( $image_tag ) { |
|---|
| 323 | |
|---|
| 324 | return wp_get_attachment_url( $image_tag ); |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | /** |
|---|
| 328 | * Generate webhook callback url for Product API |
|---|
| 329 | * |
|---|
| 330 | * @return string |
|---|
| 331 | */ |
|---|
| 332 | public static function generate_api_v3_webhook_url() { |
|---|
| 333 | $url = get_site_url(); |
|---|
| 334 | |
|---|
| 335 | return $url . GlobalConstant::API_V3_CALLBACK_URL . '?sm_token=' . self::generate_sm_token(); |
|---|
| 336 | } |
|---|
| 337 | |
|---|
| 338 | /** |
|---|
| 339 | * Extract WP product id from error message array. |
|---|
| 340 | * Iterate over array of error messages, extracting the index of the product that caused the exception. |
|---|
| 341 | * The index is then used to extract WP product ID from the $products array. |
|---|
| 342 | * Max 8 errors are displayed in the console at a time. |
|---|
| 343 | * |
|---|
| 344 | * @param array $message_array Array of string error message from ApiException |
|---|
| 345 | * @param ProductsCollection $products Collection of products |
|---|
| 346 | * |
|---|
| 347 | * @return string|false Readable error message or false on failure |
|---|
| 348 | */ |
|---|
| 349 | public static function extract_product_id_from_error_message_array( $message_array, $products ) { |
|---|
| 350 | $preg_pattern = '/\[(\d*?)\]/'; |
|---|
| 351 | $errors_to_be_displayed = []; |
|---|
| 352 | $max_err_displayed = 8; |
|---|
| 353 | try { |
|---|
| 354 | // additional condition $i < $max_err_displayed because we don't want to overwhelm the user with errors |
|---|
| 355 | $num_of_messages = count( $message_array ); |
|---|
| 356 | for ( $i = 0; $i < $num_of_messages && $i < $max_err_displayed; $i ++ ) { |
|---|
| 357 | $matches = array(); |
|---|
| 358 | preg_match( $preg_pattern, $message_array[ $i ], $matches ); |
|---|
| 359 | $arr_index = $matches[1]; // first captured parenthesized subpattern holds the index |
|---|
| 360 | $productId = $products->toArray()[ intval( $arr_index ) ]['productId']; |
|---|
| 361 | $errors_to_be_displayed[] = "{$message_array[ $i ]}. Product ID:{$productId}\n"; |
|---|
| 362 | } |
|---|
| 363 | sort( $errors_to_be_displayed ); |
|---|
| 364 | |
|---|
| 365 | return implode( $errors_to_be_displayed ); |
|---|
| 366 | } catch ( Error | Exception $ex ) { |
|---|
| 367 | return false; |
|---|
| 368 | } |
|---|
| 369 | } |
|---|
| 370 | |
|---|
| 371 | |
|---|
| 372 | /** |
|---|
| 373 | * Generate token for api v3 callback verification |
|---|
| 374 | * |
|---|
| 375 | * @return string token |
|---|
| 376 | */ |
|---|
| 377 | public static function generate_sm_token() { |
|---|
| 378 | $websiteUrl = get_site_url(); |
|---|
| 379 | $clientId = Configuration::getInstance()->getClientId(); |
|---|
| 380 | $apiKey = Configuration::getInstance()->getApiKey(); |
|---|
| 381 | return hash('sha256', substr(sha1($websiteUrl . $clientId), 0, 16) . substr($apiKey, (strlen($apiKey) - 8) / 2, 8)); |
|---|
| 382 | } |
|---|
| 383 | |
|---|
| 384 | /** |
|---|
| 385 | * @return array |
|---|
| 386 | */ |
|---|
| 387 | public static function generateDefaultMapping() { |
|---|
| 388 | return array( |
|---|
| 389 | GlobalConstant::MAP_BRAND => false, |
|---|
| 390 | GlobalConstant::MAP_MANUFACTURER => false, |
|---|
| 391 | GlobalConstant::MAP_SEASON => false, |
|---|
| 392 | GlobalConstant::MAP_COLOR => false, |
|---|
| 393 | GlobalConstant::MAP_DETAIL_1 => false, |
|---|
| 394 | GlobalConstant::MAP_DETAIL_2 => false, |
|---|
| 395 | GlobalConstant::MAP_DETAIL_3 => false, |
|---|
| 396 | GlobalConstant::MAP_DETAIL_4 => false, |
|---|
| 397 | GlobalConstant::MAP_DETAIL_5 => false, |
|---|
| 398 | ); |
|---|
| 399 | } |
|---|
| 400 | } |
|---|