PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/controllers/helpers.php

https://bitbucket.org/bayrock/gw2spidy
PHP | 326 lines | 232 code | 66 blank | 28 comment | 46 complexity | f9a3cf7d1d75dac578f539fe35aa1f24 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. <?php
  2. use \DateTime;
  3. use GW2Spidy\Application;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use GW2Spidy\DB\DisciplineQuery;
  6. use GW2Spidy\DB\ItemSubTypeQuery;
  7. use GW2Spidy\DB\ItemType;
  8. use GW2Spidy\DB\RecipeQuery;
  9. use GW2Spidy\DB\GW2Session;
  10. use GW2Spidy\DB\GoldToGemRateQuery;
  11. use GW2Spidy\DB\GemToGoldRateQuery;
  12. use GW2Spidy\DB\ItemQuery;
  13. use GW2Spidy\DB\ItemTypeQuery;
  14. use GW2Spidy\DB\SellListingQuery;
  15. use GW2Spidy\DB\WorkerQueueItemQuery;
  16. use GW2Spidy\DB\ItemPeer;
  17. use GW2Spidy\DB\BuyListingPeer;
  18. use GW2Spidy\DB\SellListingPeer;
  19. use GW2Spidy\DB\BuyListingQuery;
  20. use GW2Spidy\Util\Functions;
  21. /**
  22. * lambda used to convert URL arguments
  23. *
  24. * @param mixed $val
  25. * @return int
  26. */
  27. $toInt = function($val) {
  28. return (int) $val;
  29. };
  30. /**
  31. * generic function used for /search and /type
  32. *
  33. * @param Application $app
  34. * @param Request $request
  35. * @param ItemQuery $q
  36. * @param int $page
  37. * @param int $itemsperpage
  38. * @param array $tplVars
  39. */
  40. function item_list(Application $app, Request $request, ItemQuery $q, $page, $itemsperpage, array $tplVars = array()) {
  41. $sortByOptions = array('name', 'rarity', 'restriction_level', 'min_sale_unit_price', 'max_offer_unit_price', 'sale_availability', 'offer_availability', 'margin');
  42. foreach ($sortByOptions as $sortByOption) {
  43. if ($request->get("sort_{$sortByOption}", null)) {
  44. $sortOrder = $request->get("sort_{$sortByOption}", 'asc');
  45. $sortBy = $sortByOption;
  46. }
  47. }
  48. $sortBy = isset($sortBy) && in_array($sortBy, $sortByOptions) ? $sortBy : 'name';
  49. $sortOrder = isset($sortOrder) && in_array($sortOrder, array('asc', 'desc')) ? $sortOrder : 'asc';
  50. if (($rarityFilter = $request->get('rarity_filter', null)) !== null && is_numeric($rarityFilter) && in_array($rarityFilter, array(0,1,2,3,4,5,6))) {
  51. $q->filterByRarity($rarityFilter);
  52. }
  53. if ($minLevelFilter = $request->get('min_level', null)) {
  54. $q->filterByRestrictionLevel($minLevelFilter, \Criteria::GREATER_EQUAL);
  55. }
  56. if ($maxLevelFilter = $request->get('max_level', null)) {
  57. $q->filterByRestrictionLevel($maxLevelFilter, \Criteria::LESS_EQUAL);
  58. }
  59. $count = $q->count();
  60. if ($count > 0) {
  61. $lastpage = ceil($count / $itemsperpage);
  62. if ($page > $lastpage) {
  63. $page = $lastpage;
  64. }
  65. } else {
  66. $page = 1;
  67. $lastpage = 1;
  68. }
  69. $q->addAsColumn("margin", "min_sale_unit_price * 0.85 - max_offer_unit_price");
  70. $q->addSelectColumn("*");
  71. $q->offset($itemsperpage * ($page-1))
  72. ->limit($itemsperpage);
  73. if ($sortOrder == 'asc') {
  74. $q->addAscendingOrderByColumn($sortBy);
  75. } else if ($sortOrder == 'desc') {
  76. $q->addDescendingOrderByColumn($sortBy);
  77. }
  78. $items = $q->find();
  79. return $app['twig']->render('item_list.html.twig', $tplVars + array(
  80. 'page' => $page,
  81. 'lastpage' => $lastpage,
  82. 'items' => $items,
  83. 'rarity_filter' => $rarityFilter,
  84. 'min_level' => $minLevelFilter,
  85. 'max_level' => $maxLevelFilter,
  86. 'current_sort' => $sortBy,
  87. 'current_sort_order' => $sortOrder,
  88. ));
  89. };
  90. /**
  91. * generic function used for /search and /crafting
  92. *
  93. * @param Application $app
  94. * @param Request $request
  95. * @param ItemQuery $q
  96. * @param int $page
  97. * @param int $itemsperpage
  98. * @param array $tplVars
  99. */
  100. function recipe_list(Application $app, Request $request, RecipeQuery $q, $page, $itemsperpage, array $tplVars = array()) {
  101. $sortByOptions = array('name', 'rating', 'cost', 'karma_cost', 'sell_price', 'profit', 'sale_availability', 'offer_availability');
  102. foreach ($sortByOptions as $sortByOption) {
  103. if ($request->get("sort_{$sortByOption}", null)) {
  104. $sortOrder = $request->get("sort_{$sortByOption}", 'asc');
  105. $sortBy = $sortByOption;
  106. }
  107. }
  108. $sortBy = isset($sortBy) && in_array($sortBy, $sortByOptions) ? $sortBy : 'profit';
  109. $sortOrder = isset($sortOrder) && in_array($sortOrder, array('asc', 'desc')) ? $sortOrder : 'desc';
  110. $minLevelFilter = $request->get('min_level', null);
  111. $maxLevelFilter = $request->get('max_level', null);
  112. if ($minLevelFilter || $maxLevelFilter) {
  113. $iq = $q->useResultItemQuery();
  114. if ($minLevelFilter)
  115. $iq->filterByRestrictionLevel($minLevelFilter, \Criteria::GREATER_EQUAL);
  116. if($maxLevelFilter)
  117. $iq->filterByRestrictionLevel($maxLevelFilter, \Criteria::LESS_EQUAL);
  118. $iq->endUse();
  119. }
  120. if ($minRatingFilter = $request->get('min_rating', null)) {
  121. $q->filterByRating($minRatingFilter, \Criteria::GREATER_EQUAL);
  122. }
  123. if ($maxRatingFilter = $request->get('max_rating', null)) {
  124. $q->filterByRating($maxRatingFilter, \Criteria::LESS_EQUAL);
  125. }
  126. if($hideLocked = $request->get('hide_unlock_required', null)) {
  127. $q->filterByRequiresUnlock(0, \Criteria::EQUAL);
  128. }
  129. $q->innerJoinResultItem('ri')
  130. ->withColumn('ri.SaleAvailability','sale_availability')
  131. ->withColumn('ri.OfferAvailability','offer_availability')
  132. ->withColumn('ri.Rarity','rarity');
  133. if ($minSupplyFilter = $request->get('min_supply', null)) {
  134. $q->where('ri.SaleAvailability >= ?', $minSupplyFilter);
  135. }
  136. if ($maxSupplyFilter = $request->get('max_supply', null)) {
  137. $q->where('ri.SaleAvailability <= ?', $maxSupplyFilter);
  138. }
  139. $count = $q->count();
  140. if ($count > 0) {
  141. $lastpage = ceil($count / $itemsperpage);
  142. if ($page > $lastpage) {
  143. $page = $lastpage;
  144. }
  145. } else {
  146. $page = 1;
  147. $lastpage = 1;
  148. }
  149. $q->offset($itemsperpage * ($page-1))
  150. ->limit($itemsperpage);
  151. if ($sortOrder == 'asc') {
  152. $q->addAscendingOrderByColumn($sortBy);
  153. } else if ($sortOrder == 'desc') {
  154. $q->addDescendingOrderByColumn($sortBy);
  155. }
  156. $recipes = $q->find();
  157. return $app['twig']->render('recipe_list.html.twig', $tplVars + array(
  158. 'page' => $page,
  159. 'lastpage' => $lastpage,
  160. 'recipes' => $recipes,
  161. 'min_level' => $minLevelFilter,
  162. 'max_level' => $maxLevelFilter,
  163. 'min_rating' => $minRatingFilter,
  164. 'max_rating' => $maxRatingFilter,
  165. 'hide_unlock_required' => $hideLocked,
  166. 'min_supply' => $minSupplyFilter,
  167. 'max_supply' => $maxSupplyFilter,
  168. 'current_sort' => $sortBy,
  169. 'current_sort_order' => $sortOrder,
  170. ));
  171. };
  172. function gem_summary() {
  173. $lastSell = GemToGoldRateQuery::create()
  174. ->addDescendingOrderByColumn("rate_datetime")
  175. ->offset(-1)
  176. ->limit(1)
  177. ->findOne();
  178. $lastBuy = GoldToGemRateQuery::create()
  179. ->addDescendingOrderByColumn("rate_datetime")
  180. ->offset(-1)
  181. ->limit(1)
  182. ->findOne();
  183. if (!$lastSell || !$lastBuy) {
  184. return null;
  185. }
  186. $gemtogold = $lastSell->getRate();
  187. $goldtogem = $lastBuy->getRate();
  188. $usdtogem = 10 / 800 * 100;
  189. $poundstogem = 8.5 / 800 * 100;
  190. $eurostogem = 10 / 800 * 100;
  191. $usdtogold = (10000 / $gemtogold) * $usdtogem;
  192. return array(
  193. 'gemtogold' => $gemtogold,
  194. 'goldtogem' => $goldtogem,
  195. 'usdtogem' => $usdtogem,
  196. 'usdtogold' => $usdtogold,
  197. );
  198. }
  199. // see http://en.wikipedia.org/wiki/Greatest_common_divisor#Using_Euclid.27s_algorithm
  200. function gcd($a, $b) {
  201. if($a <= 0 || $b <=0)
  202. return 1;
  203. if ($a == $b)
  204. return $a;
  205. return $a > $b ? gcd($a - $b, $b) : gcd($a, $b - $a);
  206. }
  207. // returns the amount of times we have to craft the base recipe in order to get a multiple of the required amount
  208. function multiplier($base, $multiple) {
  209. return $base / gcd($base, $multiple);
  210. }
  211. function calculateRecipeMultiplier($item, $recipe = null) {
  212. if($recipe) {
  213. $multiplier = 1;
  214. foreach ($recipe->getIngredients() as $ingredient) {
  215. $ingredientItem = $ingredient->getItem();
  216. $ingredientRecipe = null;
  217. $ingredientRecipes = $ingredientItem->getResultOfRecipes();
  218. if (count($ingredientRecipes)) {
  219. $ingredientRecipe = $ingredientRecipes[0];
  220. $baseCount = $ingredientRecipe->getCount() * calculateRecipeMultiplier($ingredientItem, $ingredientRecipe);
  221. $multiplier *= multiplier($baseCount, $multiplier * $ingredient->getCount());
  222. }
  223. }
  224. return $multiplier;
  225. }
  226. return 1;
  227. }
  228. function buildMultiRecipeTree($item, $recipe = null, $app) {
  229. return buildRecipeTree($item, $recipe, $app, calculateRecipeMultiplier($item, $recipe));
  230. }
  231. function buildRecipeTree($item, $recipe = null, $app, $multiplier = 1) {
  232. $tree = array(
  233. 'id' => $item->getDataId(),
  234. 'name' => $item->getName(),
  235. 'href' => $app['url_generator']->generate('item', array('dataId' => $item->getDataId())),
  236. 'gw2db_href' => "http://www.gw2db.com/items/{$item->getGw2dbExternalId()}-" . Functions::slugify($item->getName()),
  237. 'rarity' => $item->getRarityName(),
  238. 'img' => $item->getImg(),
  239. 'price' => $item->getBestPrice(),
  240. 'vendor' => !!$item->getVendorPrice(),
  241. 'multiplier' => $multiplier,
  242. 'karma' => $item->getKarmaPrice(),
  243. );
  244. if ($recipe) {
  245. $recipeTree = array();
  246. foreach ($recipe->getIngredients() as $ingredient) {
  247. $ingredientItem = $ingredient->getItem();
  248. $ingredientRecipe = null;
  249. $ingredientRecipes = $ingredientItem->getResultOfRecipes();
  250. $ingredientMultiplier = $multiplier;
  251. if (count($ingredientRecipes)) {
  252. $ingredientRecipe = $ingredientRecipes[0];
  253. $ingredientMultiplier /= multiplier($ingredientRecipe->getCount(), $ingredient->getCount());
  254. }
  255. $recipeTree[] = array(buildRecipeTree($ingredientItem, $ingredientRecipe, $app, $ingredientMultiplier), $ingredient->getCount() * $multiplier);
  256. }
  257. $tree['recipe'] = array('count' => $recipe->getCount() * $multiplier, 'ingredients' => $recipeTree);
  258. }
  259. return $tree;
  260. }