Generate the diff of the files.

@param Product $product Themeisle Product.
@param array   $files Array of files.
@param bool    $recurse Whether to recurse or not.

@return mixed Diff data.
10380
private function generate_diff( $product, $files, $recurse = false ) {
		require_once( ABSPATH . 'wp-admin/includes/file.php' );
		WP_Filesystem();
		global $wp_filesystem;

		$diff = array();
		$path = str_replace( ABSPATH, $wp_filesystem->abspath(), plugin_dir_path( $product->get_basefile() ) );
		$list = $wp_filesystem->dirlist( $path, false, $recurse );
		// nothing found.
		if ( ! $list ) {
			return $diff;
		}
		$list = array_keys( self::flatten_dirlist( $list ) );

		// now let's get the valid files that actually exist.
		if ( empty( $files ) ) {
			$files = $list;
		} else {
			$files = array_intersect( $files, $list );
		}

		// fetch the calculated hashes.
		if ( ! $wp_filesystem->is_readable( $path . '/' . self::HASH_FILE ) ) {
			return new WP_Error( 'themeisle_sdk_hash_not_found', sprintf( '%s not found', self::HASH_FILE ) );
		}

		$hashes = json_decode( $wp_filesystem->get_contents( $path . '/' . self::HASH_FILE ), true );
		ksort( $hashes );

		$diff = array();
		foreach ( $files as $file ) {
			// file does not exist in the hashes.
			if ( ! array_key_exists( $file, $hashes ) ) {
				continue;
			}
			$new = md5( $wp_filesystem->get_contents( $path . $file ) );
			$old = $hashes[ $file ];

			// same hash, bail.
			if ( $new === $old ) {
				continue;
			}
			$diff[] = $file;
		}

		return $diff;
	}
614607
public function write(array $files)
    {
        $filesystem = $this->getFilesystem($this->field, $this->settings);
        $results = [];
        foreach ($files as $file => $path) {
            $results[] = $this->writeFile($filesystem, $file, $path);
        }

        return $results;
    }
81382
public static function directoryDiff($source, $target)
    {
        $sourceFiles = self::globr($source, '*');
        $targetFiles = self::globr($target, '*');

        $sourceFiles = array_map(function ($file) use ($source) {
            return str_replace($source, '', $file);
        }, $sourceFiles);

        $targetFiles = array_map(function ($file) use ($target) {
            return str_replace($target, '', $file);
        }, $targetFiles);

        $diff = array_diff($targetFiles, $sourceFiles);

        return array_values($diff);
    }
260618
private Map<Product, Product> diffProducts(List<Product> pcm1Products, List<Product> pcm2Products, PCMElementComparator comparator, DiffResult result) {
        List<Product> commonProducts = new ArrayList<Product>();
        List<Product> productsOnlyInPCM1 = new ArrayList<Product>();
        List<Product> productsOnlyInPCM2 = new ArrayList<Product>(pcm2Products);

        Map<Product, Product> equivalentProducts = new HashMap<Product, Product>();

        for (Product p1 : pcm1Products) {

            boolean similarProduct = false;

            for (Product p2 : pcm2Products) {
                similarProduct = comparator.similarProduct(p1, p2);
                if (similarProduct) {
                    commonProducts.add(p1);
                    productsOnlyInPCM2.remove(p2);
                    equivalentProducts.put(p1, p2);
                    break;
                }
            }

            if (!similarProduct) {
                productsOnlyInPCM1.add(p1);
            }

        }

        result.setCommonProducts(commonProducts);
        result.setProductsOnlyInPCM1(productsOnlyInPCM1);
        result.setProductsOnlyInPCM2(productsOnlyInPCM2);

        return equivalentProducts;
    }
1004409
protected function removeAssetCache($file, $recursive)
    {
        $files = $this->asset->isJavascript($file) ? $this->asset->getParser()->javascriptFiles($file) : $this->asset->getParser()->stylesheetFiles($file);

        array_push($files, $this->asset->getParser()->absoluteFilePath($file));

        foreach ($files as $file)
        {
            $removed = $this->asset->getGenerator()->cachedFile($file)->remove();

            if ($removed === false) {
                $this->writeln(PHP_EOL . "<warning> failed to find/remove cache for {$file}</warning>");
            }
        }
    }
929790
public function lint($files = [], $cache = true)
    {
        if (empty($files)) {
            $files = $this->getFiles();
        }

        $processCallback = is_callable($this->processCallback) ? $this->processCallback : function () {
        };

        $errors = [];
        $running = [];
        $newCache = [];

        while (!empty($files) || !empty($running)) {
            for ($i = count($running); !empty($files) && $i < $this->processLimit; ++$i) {
                $file = array_shift($files);
                $filename = $file->getRealPath();
                $relativePathname = $file->getRelativePathname();
                if (!isset($this->cache[$relativePathname]) || $this->cache[$relativePathname] !== md5_file($filename)) {
                    $lint = $this->createLintProcess($filename);
                    $running[$filename] = [
                        'process' => $lint,
                        'file' => $file,
                        'relativePath' => $relativePathname,
                    ];
                    $lint->start();
                } else {
                    $newCache[$relativePathname] = $this->cache[$relativePathname];
                }
            }

            foreach ($running as $filename => $item) {
                /** @var Lint $lint */
                $lint = $item['process'];
                if ($lint->isRunning()) {
                    continue;
                }

                unset($running[$filename]);
                if ($lint->hasSyntaxError()) {
                    $processCallback('error', $item['file']);
                    $errors[$filename] = array_merge(['file' => $filename], $lint->getSyntaxError());
                } else {
                    $newCache[$item['relativePath']] = md5_file($filename);
                    $processCallback('ok', $item['file']);
                }
            }
        }

        $cache && Cache::put($newCache);

        return $errors;
    }
858742
public static function walkCopy(
        array $array,
        callable $callback,
        $recurse = false,
        $path = '',
        $considerLeaves = true
    ) {
        return static::walk(
            $array,
            $callback,
            $recurse,
            $path,
            $considerLeaves
        );
    }
1241526
public function tax(Product $product)
    {
        $tax = $this->money($product);

        if (! $product->taxable || $product->freebie) {
            return $tax;
        }

        $value    = $this->value($product);
        $discount = $this->discount($product);

        $value = $value->subtract($discount);
        $tax   = $value->multiply($product->rate->float());

        return $tax;
    }
569894
public function load( $product ) {
		$this->product = $product;

		$notifications       = apply_filters( 'themeisle_sdk_registered_notifications', [] );
		$notifications       = array_filter(
			$notifications,
			function ( $value ) {
				if ( ! isset( $value['id'] ) ) {
					return false;
				}
				if ( get_option( $value['id'], '' ) !== '' ) {
					return false;
				}

				return apply_filters( $value['id'] . '_should_show', true );
			}
		);
		self::$notifications = $notifications;
		add_action( 'admin_notices', array( __CLASS__, 'show_notification' ) );
		add_action( 'wp_ajax_themeisle_sdk_dismiss_notice', array( __CLASS__, 'dismiss' ) );
		add_action( 'admin_head', array( __CLASS__, 'setup_notifications' ) );

		return $this;
	}
610737
public function newAction(Product $product, Request $request)
    {
        $restock = new RestockTransaction();
        $restock->setProduct($product);

        $form = $this->createForm(new RestockTransactionType(), $restock);

        if ($request->getMethod() == 'POST')
        {
            $form->bindRequest($request);

            if ($form->isValid())
            {
                try
                {
                    // For now, we always post the RestockTransaction, but
                    // later we'll check to see if this is a future transaction
                    $restock->post();

                    $em = $this->getDoctrine()->getEntityManager();
                    $em->persist($restock);
                    $em->flush();

                    return $this->redirect($this->generateUrl('Seller_product_show', array(
                        'id' => $product->getId(),
                    )));
                }
                catch (\Exception $e)
                {
                    // could not Restock Product
                }
            }
        }

        return $this->render('HarvestCloudCoreBundle:Seller/RestockTransaction:new.html.twig', array(
          'form'    => $form->createView(),
          'product' => $product,
        ));
    }
1192342
public function sendNewProductToManagerAndOwner(Product $product)
    {
        $productOwner = $product->productOwner;
        $mailVars = [
            '{productId}' => $product->id,
            '{title}' => $product->translation->title,
            '{ownerId}' => $productOwner->id,
            '{ownerEmail}' => $productOwner->email,
            '{owner}' => !(empty($productOwner->profile->name . ' ' . $productOwner->profile->surname)) ?
                $productOwner->profile->name . ' ' . $productOwner->profile->surname : $productOwner->profile->info,
            '{link}' => Html::a(
                $product->translation->title,
                Url::toRoute('/shop/product/save?id=' . $product->id . '&languageId=' . Language::getCurrent()->id, true)),

        ];

        //Send mail to manager
        $mailTemplate = $this->createMailTemplate('new-product-to-manager', $mailVars);
        $partnerManagerEmail = \Yii::$app->getModule('shop')->partnerManagerEmail;

        if (!empty($mailTemplate) && !empty($partnerManagerEmail)) {
            $subject = $mailTemplate->getSubject();
            $bodyParams = ['bodyContent' => $mailTemplate->getBody()];

            $sendFrom = [\Yii::$app->get('shopMailer')->transport->getUsername() => \Yii::$app->name ?? parse_url(Url::base(true), PHP_URL_HOST)];

            $this->sendMessage($sendFrom, $partnerManagerEmail, $subject, $bodyParams);
        }

        //Send mail to partner
        $mailTemplate = $this->createMailTemplate('new-product-to-partner', $mailVars);
        if (!empty($mailTemplate) && !empty($productOwner->email)) {
            $subject = $mailTemplate->getSubject();
            $bodyParams = ['bodyContent' => $mailTemplate->getBody()];

            $sendFrom = [\Yii::$app->get('shopMailer')->transport->getUsername() => \Yii::$app->name ?? parse_url(Url::base(true), PHP_URL_HOST)];

            $this->sendMessage($sendFrom, $productOwner->email, $subject, $bodyParams);
        }
    }
460623
public function set($product_id, array $products)
    {
        $this->delete(array('product_id' => $product_id));

        $added = $count = 0;
        foreach ($products as $product) {

            $count++;

            $data = array(
                'product_id' => $product_id,
                'item_product_id' => $product['product_id']
            );

            if ($this->add($data)) {
                $added++;
            }
        }

        return $count && $added == $count;
    }
1100135
public static function array_diff_multi($array1, $array2)
    {

        $res = array();
        foreach ($array1 as $entry) {
            if (!in_array($entry, $array2)) {
                $res[] = $entry;
            }
        }

        return $res;
    }
969812
public function listDirectories(bool $recursion = true): array {
		$filter = new class extends Filter {
			public function filter(File $dirOrPath): bool {
				/**
				 * @var File $dirOrPath
				 */
				return $dirOrPath->isDirectory();
			}
		};
		$index  = $this->addFilter($filter);
		$result = $this->listContents($recursion);
		$this->removeFilter($index);

		return $result;
	}
172701
public function save(ProductContract $product, array $attributes = [])
    {
        $result = $product->save();

        $details = [];
        foreach ($attributes as $key => $value) {
            if ($value) {
                $details[$key] = compact('value');
            }
        }
        $product->attributes()->sync($details);

        return $result;
    }
916063
protected function prepare(array $product)
    {
        $data = array();
        foreach ($this->job['data']['header'] as $key => $value) {
            $data[$key] = isset($product[$key]) ? $product[$key] : '';
        }

        $this->prepareImages($data, $product);
        $this->preparePrice($data, $product);
        $this->prepareImages($data, $product);

        return $data;
    }
170583
protected function indexProductTranslations(array $product)
    {
        if (empty($product['translation'])) {
            return false;
        }

        $indexed = 0;

        foreach ($product['translation'] as $language => $translation) {
            $translation += $product;
            $snippet = $this->search->getSnippet($translation, $language);
            $indexed += (int) $this->search->setIndex($snippet, 'product', $product['product_id'], $language);
        }

        return $indexed > 0;
    }