src/Controller/ClientController.php line 902

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\PublicKey;
  4. use App\Form\ClientAccountFormType;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\Mailer\MailerInterface;
  7. use Symfony\Component\Security\Core\User\UserInterface;
  8. /**
  9.  * Class ClientController
  10.  * @package App\Controller
  11.  */
  12. class ClientController extends BaseController
  13. {
  14.     /**
  15.      * Client List
  16.      */
  17.     public function index()
  18.     {
  19.         $sql "SELECT 
  20.                     client_key,
  21.                     name,
  22.                     is_active,
  23.                     copyright,
  24.                     has_consolidated_supporting_feed,
  25.                     isin_access
  26.                 FROM feeds.CLIENT 
  27.                 ORDER BY is_active DESC, name";
  28.         $db $this->getDoctrine()->getConnection();
  29.         $stmt $db->prepare($sql);
  30.         $stmt->execute();
  31.         $clients $stmt->fetchAll();
  32.         $data = array(
  33.             'clients' => $clients
  34.         );
  35.         return $this->render('client/list.html.twig'$data);
  36.     }
  37.     public function viewAccount(Request $request$accountKey)
  38.     {
  39.         $sql "SELECT
  40.                     client_account_key,
  41.                     client_name,
  42.                     description,
  43.                     account_name,
  44.                     password,
  45.                     start_date,
  46.                     expire_date,
  47.                     contact,
  48.                     ip_whitelist,
  49.                     notes,
  50.                     is_active
  51.                 FROM feeds.CLIENT_ACCOUNT
  52.                 WHERE client_account_key = :account_key";
  53.         $db $this->getDoctrine()->getConnection();
  54.         $stmt $db->prepare($sql);
  55.         $stmt->bindValue(':account_key'$accountKey\PDO::PARAM_INT);
  56.         $stmt->execute();
  57.         $data['accounts'] = [];
  58.         while ($row $stmt->fetch()) {
  59.             $data['account'] = $row;
  60.         }
  61.        $sql "SELECT
  62.                     key_string,
  63.                     key_type
  64.                 FROM feeds.CLIENT_ACCOUNT_TO_ACCESS
  65.                 WHERE client_account_fkey = :account_key";
  66.         $db $this->getDoctrine()->getConnection();
  67.         $stmt $db->prepare($sql);
  68.         $stmt->bindValue(':account_key'$accountKey\PDO::PARAM_INT);
  69.         $stmt->execute();
  70.         $data['keys'] = [];
  71.         while ($row $stmt->fetch()) {
  72.             $data['keys'][] = $row;
  73.         }
  74.         return $this->render('client/account_view.html.twig'$data);
  75.     }
  76.     /**
  77.      * @return \Symfony\Component\HttpFoundation\Response
  78.      */
  79.     public function showAccount()
  80.     {
  81.         $sql "SELECT
  82.                     CA.client_account_key,
  83.                     CA.client_name,
  84.                     CA.account_name,
  85.                     CA.password,
  86.                     (SELECT
  87.                         GROUP_CONCAT(CTH.hostname SEPARATOR ',')
  88.                      FROM feeds.CLIENT_TO_HOSTNAME AS CTH
  89.                      WHERE CTH.client_account_fkey = CA.client_account_key
  90.                     ) AS hostnames,
  91.                     CA.start_date,
  92.                     CA.expire_date,
  93.                     CA.contact,
  94.                     CA.notes,
  95.                     CA.is_active
  96.                 FROM feeds.CLIENT_ACCOUNT AS CA
  97.                 ORDER BY CA.is_active DESC, CA.client_name";
  98.         $db $this->getDoctrine()->getConnection();
  99.         $stmt $db->prepare($sql);
  100.         $stmt->execute();
  101.         $data['accounts'] = [];
  102.         while ($row $stmt->fetch()) {
  103.             $row['hostnames'] = explode(','$row['hostnames']);
  104.             $data['accounts'][] = $row;
  105.         }
  106.         return $this->render('client/account.html.twig'$data);
  107.     }
  108.     /**
  109.      * @param Request $request
  110.      * @param null    $accountKey
  111.      * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
  112.      * @throws \Exception
  113.      */
  114.     public function editAccount(Request $requestMailerInterface $mailerUserInterface $user$accountKey null)
  115.     {
  116.         $account = [];
  117.         if ($accountKey) {
  118.             $sql "SELECT 
  119.                         CA.client_account_key,
  120.                         CA.client_name,
  121.                         CA.description,
  122.                         CA.account_name,
  123.                         (SELECT
  124.                             GROUP_CONCAT(CTH.hostname SEPARATOR ',')
  125.                          FROM feeds.CLIENT_TO_HOSTNAME AS CTH
  126.                          WHERE CTH.client_account_fkey = CA.client_account_key
  127.                         ) AS hostnames,
  128.                         CA.start_date,
  129.                         CA.expire_date,
  130.                         CA.contact,
  131.                         CA.notes,
  132.                         CA.ip_whitelist,
  133.                         CA.is_active
  134.                     FROM feeds.CLIENT_ACCOUNT AS CA
  135.                     WHERE client_account_key = :account_key";
  136.             $db $this->getDoctrine()->getConnection();
  137.             $stmt $db->prepare($sql);
  138.             $stmt->bindValue(':account_key'$accountKey\PDO::PARAM_INT);
  139.             $stmt->execute();
  140.             $account $stmt->fetch();
  141.             $account['hostnames'] = explode(','$account['hostnames']);
  142.             $account['expire_date'] = $account['expire_date'] ? new \DateTime($account['expire_date']) : null;
  143.         }
  144.         !empty($account['hostnames']) ?: $account['hostnames'] = [""""""];
  145.         $sql "SELECT 
  146.                     key_string,
  147.                     key_type,
  148.                     key_hash
  149.                 FROM feeds.CLIENT_ACCOUNT_TO_ACCESS
  150.                 WHERE client_account_fkey = :account_key
  151.         ";
  152.         $db $this->getDoctrine()->getConnection();
  153.         $stmt $db->prepare($sql);
  154.         $stmt->bindValue(':account_key'$accountKey\PDO::PARAM_INT);
  155.         $stmt->execute();
  156.         $keys = [];
  157.         while ($row $stmt->fetch()) {
  158.             $key = new PublicKey();
  159.             $key->setKeyString($row['key_string']);
  160.             $key->setKeyType($row['key_type']);
  161.             $keys[] = $key;
  162.         }
  163.         if (empty($keys) && !$accountKey) {
  164.             $keys = [new PublicKey()];
  165.         }elseif(empty($keys)){
  166.             $keys = [];
  167.         }
  168.         $account['public_keys'] = $keys;
  169.         $form $this->createForm(ClientAccountFormType::class, $account);
  170.         $form->handleRequest($request);
  171.         if ($form->isSubmitted() && $form->isValid()) {
  172.             $sql "INSERT INTO feeds.CLIENT_ACCOUNT
  173.                     SET client_account_key = :client_account_key,
  174.                         client_name = :client_name,
  175.                         description = :description,
  176.                         account_name = :account_name,
  177.                         expire_date = :expire_date,
  178.                         contact = :contact,
  179.                         ip_whitelist = :ip_whitelist,
  180.                         notes = :notes,
  181.                         is_active = :is_active,
  182.                         meta_date_time_created = NOW()
  183.                     ON DUPLICATE KEY UPDATE
  184.                         client_name = VALUES(client_name),
  185.                         description = VALUES(description),
  186.                         account_name = VALUES(account_name),
  187.                         expire_date = VALUES(expire_date),
  188.                         contact = VALUES(contact),
  189.                         ip_whitelist = VALUES(ip_whitelist),
  190.                         notes = VALUES(notes),
  191.                         is_active = VALUES(is_active)
  192.             ";
  193.             $db $this->getDoctrine()->getConnection();
  194.             $stmt =  $db->prepare($sql);
  195.             $expireDate $form->get('expire_date')->getData() ? $form->get('expire_date')->getData()->format('Y-m-d') : null;
  196.             $accountKey $form->get('client_account_key')->getData();
  197.             $stmt->bindValue(':client_account_key'$accountKey\PDO::PARAM_INT);
  198.             $stmt->bindValue(':client_name'$form->get('client_name')->getData(), \PDO::PARAM_STR);
  199.             $stmt->bindValue(':description'$form->get('description')->getData(), \PDO::PARAM_STR);
  200.             $stmt->bindValue(':account_name'$form->get('account_name')->getData(), \PDO::PARAM_STR);
  201.             $stmt->bindValue(':expire_date'$expireDate\PDO::PARAM_STR);
  202.             $stmt->bindValue(':contact'$form->get('contact')->getData(), \PDO::PARAM_STR);
  203.             $stmt->bindValue(':ip_whitelist'$form->get('ip_whitelist')->getData(), \PDO::PARAM_STR);
  204.             $stmt->bindValue(':notes'$form->get('notes')->getData(), \PDO::PARAM_STR);
  205.             $stmt->bindValue(':is_active'$form->get('is_active')->getData(), \PDO::PARAM_INT);
  206.             $stmt->execute();
  207.             // If we are adding a new account, the key will be empty, so lets get the insert ID to use later
  208.             if (!$accountKey) {
  209.                 $accountKey $db->lastInsertId();
  210.             }
  211.             // Remove any previous hostnames that are not in the request
  212.             $hostnames $form->get('hostnames')->getData();
  213.             $sql "DELETE FROM feeds.CLIENT_TO_HOSTNAME
  214.                     WHERE client_account_fkey = :client_account_fkey
  215.                       AND hostname NOT IN (:hostnames)";
  216.             $db->executeQuery($sql,
  217.                                 array(':client_account_fkey' => $accountKey,
  218.                                       ':hostnames' => $hostnames),
  219.                                 array(':client_account_fkey' => \PDO::PARAM_INT,
  220.                                       ':hostnames' => \Doctrine\DBAL\Connection::PARAM_STR_ARRAY));
  221.             $values = [];
  222.             $params = [];
  223.             $types = [];
  224.             foreach ($hostnames as $key => $hostname) {
  225.                 $values[] = "(:client_account_fkey{$key}, :hostname{$key}, NOW())";
  226.                 $params[":client_account_fkey{$key}"] = $accountKey;
  227.                 $types[":client_account_fkey{$key}"] = \PDO::PARAM_INT;
  228.                 $params[":hostname{$key}"] = $hostname;
  229.                 $types[":hostname{$key}"] = \PDO::PARAM_STR;
  230.             }
  231.             // Insert any new host names
  232.             $values implode(','$values);
  233.             $sql "INSERT IGNORE INTO feeds.CLIENT_TO_HOSTNAME
  234.                         (client_account_fkey,
  235.                          hostname,
  236.                          meta_date_time_created)
  237.                     VALUES {$values}";
  238.             $db->executeQuery($sql$params$types);
  239.             // clear previous keys
  240.             $sql "DELETE FROM feeds.CLIENT_ACCOUNT_TO_ACCESS 
  241.                     WHERE client_account_fkey = :client_account_fkey";
  242.             $db $this->getDoctrine()->getConnection();
  243.             $stmt =  $db->prepare($sql);
  244.             $stmt->bindValue(':client_account_fkey'$accountKey\PDO::PARAM_INT);
  245.             $stmt->execute();
  246.             // update public keys
  247.             $keys $form->get('public_keys')->getData();
  248.             foreach ($keys as $key) {
  249.                 $sql "INSERT INTO feeds.CLIENT_ACCOUNT_TO_ACCESS
  250.                         SET client_account_fkey = :client_account_fkey,
  251.                             key_string = :key_string,
  252.                             key_type = :key_type,
  253.                             key_hash = :key_hash,
  254.                             meta_date_time_created = NOW()
  255.                         ON DUPLICATE KEY UPDATE
  256.                             key_string = VALUES(key_string),
  257.                             key_type = VALUES(key_type),
  258.                             key_hash = VALUES(key_hash)";
  259.                 $db $this->getDoctrine()->getConnection();
  260.                 $stmt =  $db->prepare($sql);
  261.                 $stmt->bindValue(':client_account_fkey'$accountKey\PDO::PARAM_INT);
  262.                 $stmt->bindValue(':key_string'$key->getKeyString(), \PDO::PARAM_STR);
  263.                 $stmt->bindValue(':key_type'$key->getKeyType(), \PDO::PARAM_STR);
  264.                 $key->setKeyHash();
  265.                 $stmt->bindValue(':key_hash'$key->getKeyHash(), \PDO::PARAM_STR);
  266.                 $stmt->execute();
  267.             }
  268.             $this->addFlash('success''Account successfully saved');
  269.             /*  Disable client and its feed when marking account status as inactive
  270.              *  AND this client does not have multiple active accounts
  271.              * */
  272.             $clientName $form->get('client_name')->getData();
  273.             $isActive = (int)$form->get('is_active')->getData();
  274.             if ($isActive === && $this->hasMultipleActiveAccount($clientName) === false){
  275.                 $clientKey $this->getClientKeyByName($clientName);
  276.                 $activeChildren array_filter($this->getChildren($clientKey), function($child) {
  277.                     return $child['is_active'];
  278.                 });
  279.                 if (empty($activeChildren)) {
  280.                     $this->disableClientFeed($mailer$user$request$clientKey);
  281.                     $this->addFlash('success'"Account is marked as inactive and All the feeds associated with $clientName are disabled as well");
  282.                 } else {
  283.                     $this->addFlash('warning'"Account is marked as inactive BUT the feeds associated with $clientName are still active because this Client has active Children");
  284.                 }
  285.             }
  286.             return $this->redirectToRoute('client_account_list');
  287.         }
  288.         return $this->render('client/account_edit.html.twig', [
  289.             'clientAccountForm' => $form->createView()
  290.         ]);
  291.     }
  292.     public function removeAccount($accountKeyMailerInterface $mailerRequest $requestUserInterface $user)
  293.     {
  294.         $sql "UPDATE feeds.CLIENT_ACCOUNT 
  295.                 SET is_active = 0 
  296.                 WHERE client_account_key = ?";
  297.         $db $this->getDoctrine()->getConnection();
  298.         $db->executeQuery($sql, [$accountKey], [\PDO::PARAM_INT]);
  299.         $this->addFlash('success''Account successfully removed');
  300.         $sql "SELECT client_name    
  301.                 FROM feeds.CLIENT_ACCOUNT
  302.                 WHERE client_account_key = :client_account_key";
  303.         $db $this->getDoctrine()->getConnection();
  304.         $stmt $db->prepare($sql);
  305.         $stmt->bindValue(":client_account_key"$accountKey\PDO::PARAM_INT);
  306.         $stmt->execute();
  307.         $clientName $stmt->fetchColumn();
  308.         /* Disable client and its feed only if this client does not have multiple active accounts
  309.          */
  310.         if ($this->hasMultipleActiveAccount($clientName) === false){
  311.             $clientKey $this->getClientKeyByName($clientName);
  312.             $activeChildren array_filter($this->getChildren($clientKey), function($child) {
  313.                 return $child['is_active'];
  314.             });
  315.             if (empty($activeChildren)) {
  316.                 $this->disableClientFeed($mailer$user$request$clientKey);
  317.                 $this->addFlash('success'"All the feeds associated with $clientName are disabled as well");
  318.             } else {
  319.                 $this->addFlash('warning'"Account is marked as inactive BUT the feeds associated with $clientName are still active because this Client has active Children");
  320.             }
  321.         }
  322.         return $this->redirectToRoute('client_account_list');
  323.     }
  324.     /**
  325.      * @param $clientKey
  326.      * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
  327.      */
  328.     public function getClient($clientKey)
  329.     {
  330.         $genericClientKey $this->getGenericClientKey();
  331.         $client $this->getClientInfo($clientKey);
  332.         $children $this->getChildren($clientKey);
  333.         $activeChildren array_filter($children, function($child) {
  334.             return $child['is_active'];
  335.         });
  336.         $data = array(
  337.             'client' => $client,
  338.             'children' => $children,
  339.             'has_active_children' => (bool) count($activeChildren),
  340.             'client_key' => $clientKey,
  341.             'generic_client_key' => $genericClientKey,
  342.             'client_list' => $this->getEligibleParents()
  343.         );
  344.         if (!$client) {
  345.             $this->addFlash('error''Client doesn\'t exist. Invalid key');
  346.             return $this->redirectToRoute('client_list');
  347.         } else {
  348.             if (!$client['is_active']) {
  349.                 $this->addFlash('warning'"This client is currently disabled!");
  350.             }
  351.             $sql "SELECT
  352.                         F.feed_number,
  353.                         F.is_normalized,
  354.                         CTF.feed_fkey,
  355.                         CTF.is_active
  356.                     FROM feeds.CLIENT_TO_FEED AS CTF
  357.                     JOIN feeds.FEED AS F
  358.                       ON CTF.feed_fkey = F.feed_key
  359.                     WHERE CTF.client_fkey = :client_key
  360.                     ORDER BY IF(CTF.is_active = 1, 1, 0) DESC, F.feed_number";
  361.             $db $this->getDoctrine()->getConnection();
  362.             $stmt $db->prepare($sql);
  363.             $stmt->bindValue(":client_key"$clientKey\PDO::PARAM_INT);
  364.             $stmt->execute();
  365.             $feeds $stmt->fetchAll();
  366.             $data['feeds'] = $feeds;
  367.             $hasActiveFeed 0;
  368.             foreach ($feeds as $feed) {
  369.                 if ($feed['is_active'] == 1) {
  370.                     $hasActiveFeed 1;
  371.                     break;
  372.                 }
  373.             }
  374.             $data['has_active_feed'] = $hasActiveFeed;
  375.             //get GENERIC feeds that are not in current client
  376.             $sql "SELECT DISTINCT
  377.                        F.feed_key,
  378.                        F.feed_number,
  379.                        F.is_normalized
  380.                     FROM feeds.CLIENT_TO_FEED AS CTF
  381.                     JOIN feeds.FEED AS F
  382.                       ON CTF.feed_fkey = F.feed_key
  383.                     WHERE CTF.client_fkey = :generic_client_fkey
  384.                       AND F.feed_number NOT IN
  385.                       (
  386.                         SELECT DISTINCT F1.feed_number
  387.                         FROM feeds.CLIENT_TO_FEED AS CTF1
  388.                         JOIN feeds.FEED AS F1
  389.                           ON CTF1.feed_fkey = F1.feed_key
  390.                         WHERE CTF1.client_fkey = :client_key
  391.                        )
  392.                     ORDER BY F.feed_number";
  393.             $db $this->getDoctrine()->getConnection();
  394.             $stmt $db->prepare($sql);
  395.             $stmt->bindValue(":client_key"$clientKey\PDO::PARAM_INT);
  396.             $stmt->bindValue(":generic_client_fkey"$genericClientKey\PDO::PARAM_INT);
  397.             $stmt->execute();
  398.             $data['generic_feeds'] = $stmt->fetchAll();
  399.         }
  400.         return $this->render('client/edit.html.twig'$data);
  401.     }
  402.     /** Add new client view
  403.      *
  404.      * @return \Symfony\Component\HttpFoundation\Response
  405.      */
  406.     public function addClient()
  407.     {
  408.         $colMeta $this->getClientInfo();
  409.         $data = array(
  410.             'client' => $colMeta,
  411.             'client_key' => null,
  412.             'children' => null,
  413.             'has_active_children' => false,
  414.             'has_active_feed' => 0,
  415.             'client_list' => $this->getEligibleParents()
  416.         );
  417.         return $this->render('client/edit.html.twig'$data);
  418.     }
  419.     /**
  420.      * @param Request $request
  421.      * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
  422.      */
  423.     public function updateClient(Request $requestMailerInterface $mailerUserInterface $user)
  424.     {
  425.         $clientKey $request->request->get("client_key");
  426.         $parentClientKey $request->request->get("parent_client_key");
  427.         $clientName $request->request->get("client_name");
  428.         $feedDir $request->request->get("feed_dir");
  429.         $headerType $request->request->get("header_type");
  430.         $fileFormat $request->request->get("file_format");
  431.         $compressionFormat $request->request->get("compression_format");
  432.         $copyright $request->request->getInt("copyright");
  433.         $hasDelta $request->request->getInt("has_delta");
  434.         $isinAccess $request->request->getInt("isin_access");
  435.         $hasConsolidatedSupportingFeed $request->request->getInt("has_consolidated_supporting_feed");
  436.         $isActive $request->request->getInt("is_active");
  437.         $error false;
  438.         if (!$clientName || !$feedDir) {
  439.             $this->addFlash('error'"Client Name or Feed Dir must not be blank!");
  440.             $error true;
  441.         }
  442.         # Validate that this client and the selected parent are not the same
  443.         if (($clientKey && $parentClientKey) && ($clientKey == $parentClientKey)) {
  444.             $this->addFlash('error'"A Client can not be its own Parent!");
  445.             $error true;
  446.         }
  447.         # Validate that the parent is not itself a child, and that it is active
  448.         if ($parentClientKey) {
  449.             $parent $this->getClientInfo($parentClientKey);
  450.             if (!empty($parent['parent_client_fkey'])) {
  451.                 $this->addFlash('error'"The Parent you selected is a child of another Client. This is not allowed!");
  452.                 $error true;
  453.             }
  454.             if (!$parent['is_active']) {
  455.                 $this->addFlash('error'"The Parent you selected is inactive. You must make it active to add this Client as a Child.");
  456.                 $error true;
  457.             }
  458.         }
  459.         # Validate that if we are marking this client as inactive, none of its children are active
  460.         if ($clientKey && !$isActive) {
  461.             $activeChildren array_filter($this->getChildren($clientKey), function($child) {
  462.                 return $child['is_active'];
  463.             });
  464.             if (count($activeChildren)) {
  465.                 $this->addFlash('error'"This Client has child accounts that are active. You can not make this Client inactive.");
  466.                 $error true;
  467.             }
  468.         }
  469.         if ($error) {
  470.             return $clientKey $this->redirectToRoute('client_view', array('clientKey' => $clientKey)) : $this->redirectToRoute('client_add');
  471.         }
  472.         if ($clientKey) {
  473.             $data['client_key'] = $clientKey;
  474.             $sql "SELECT COUNT(*)
  475.                     FROM feeds.CLIENT_TO_FEED AS CTF
  476.                     WHERE CTF.client_fkey = :client_key 
  477.                     AND CTF.is_active = 1";
  478.             $db $this->getDoctrine()->getConnection();
  479.             $stmt $db->prepare($sql);
  480.             $stmt->bindValue(":client_key"$clientKey\PDO::PARAM_INT);
  481.             $stmt->execute();
  482.             $activeFeeds $stmt->fetchColumn();
  483.             if ($activeFeeds && $isActive === 0) {
  484.                 // Set all feeds associated with this client to inactive
  485.                 $this->disableClientFeed($mailer$user$request$clientKey);
  486.                 $this->addFlash('info''All feeds for this client have been marked inactive');
  487.             }
  488.         }
  489.         $sql "INSERT INTO feeds.CLIENT
  490.                     SET client_key = :client_key,
  491.                         parent_client_fkey = :parent_client_key,
  492.                         name =:name,
  493.                         is_active =:is_active,
  494.                         feed_dir =:feed_dir,
  495.                         header_type= :header_type,
  496.                         copyright =:copyright,
  497.                         has_delta =:has_delta,
  498.                         has_consolidated_supporting_feed =:has_consolidated_supporting_feed,
  499.                         file_format =:file_format,
  500.                         compression_format =:compression_format,
  501.                         isin_access =:isin_access,
  502.                         meta_date_time_created = NOW()
  503.                    ON DUPLICATE KEY UPDATE
  504.                         parent_client_fkey = :parent_client_key,
  505.                         name = VALUES(name),
  506.                         is_active = VALUES(is_active),
  507.                         feed_dir = VALUES(feed_dir),
  508.                         header_type = VALUES(header_type),
  509.                         copyright = VALUES(copyright),
  510.                         has_delta = VALUES(has_delta),
  511.                         has_consolidated_supporting_feed = VALUES(has_consolidated_supporting_feed),
  512.                         file_format = VALUES(file_format),
  513.                         compression_format = VALUES(compression_format),
  514.                         isin_access = VALUES(isin_access),
  515.                         meta_date_time_changed = VALUES(meta_date_time_changed)";
  516.         $db $this->getDoctrine()->getConnection();
  517.         $stmt $db->prepare($sql);
  518.         $stmt->bindValue(":client_key"$clientKey\PDO::PARAM_INT);
  519.         $stmt->bindValue(":parent_client_key"$parentClientKey\PDO::PARAM_INT);
  520.         $stmt->bindValue(":name"$clientName\PDO::PARAM_STR);
  521.         $stmt->bindValue(":is_active"$isActive\PDO::PARAM_INT);
  522.         $stmt->bindValue(":feed_dir"$feedDir\PDO::PARAM_STR);
  523.         $stmt->bindValue(":header_type"$headerType\PDO::PARAM_STR);
  524.         $stmt->bindValue(":copyright"$copyright\PDO::PARAM_INT);
  525.         $stmt->bindValue(":has_delta"$hasDelta\PDO::PARAM_INT);
  526.         $stmt->bindValue(":has_consolidated_supporting_feed"$hasConsolidatedSupportingFeed\PDO::PARAM_INT);
  527.         $stmt->bindValue(":file_format"$fileFormat\PDO::PARAM_STR);
  528.         $stmt->bindValue(":compression_format"$compressionFormat\PDO::PARAM_STR);
  529.         $stmt->bindValue(":isin_access"$isinAccess\PDO::PARAM_INT);
  530.         $stmt->execute();
  531.         if (!$clientKey) {
  532.             $clientKey $db->lastInsertId();
  533.         }
  534.         $this->validateISINInClientFeed($clientKey);
  535.         $data['client'] =  $this->getClientInfo($clientKey);
  536.         $data['client_key'] = $clientKey;
  537.         $this->addFlash('success''Client Info saved successfully!');
  538.         return $this->render('client/edit-post.html.twig'$data);
  539.     }
  540.     /**
  541.      * @param Request $request
  542.      * @param $clientKey
  543.      * @return mixed
  544.      */
  545.     public function updateClientToFeed(Request $request$clientKey){
  546.         $action $request->request->get("action");
  547.         $feedFkey $request->request->get("feed_fkey");
  548.         $feedNumber $request->request->get("feed_number");
  549.         $this->validateISINInClientFeed($clientKey);
  550.         if ($action === 'active'){
  551.             $this->activeClientToFeed($clientKey$feedFkey1);
  552.             $this->addFlash('success'"FEED{$feedNumber} is enabled from this client!");
  553.         } elseif ($action === 'inactive'){
  554.             $this->activeClientToFeed($clientKey$feedFkey0);
  555.             $this->addFlash('success'"FEED{$feedNumber} is disabled from this client!");
  556.         }
  557.         return $this->redirectToRoute('client_view', array('clientKey' => $clientKey));
  558.     }
  559.     /** Enable/Disable a feed from client
  560.      *
  561.      * @param $clientKey
  562.      * @param $feedFkey
  563.      * @param $active
  564.      */
  565.     protected function activeClientToFeed($clientKey$feedFkey$active)
  566.     {
  567.         $sql "UPDATE feeds.CLIENT_TO_FEED
  568.                   SET is_active = :active
  569.                 WHERE client_fkey = :client_fkey 
  570.                   AND feed_fkey = :feed_fkey";
  571.         $db $this->getDoctrine()->getConnection();
  572.         $stmt $db->prepare($sql);
  573.         $stmt->bindValue(':client_fkey'$clientKey\PDO::PARAM_INT);
  574.         $stmt->bindValue(':feed_fkey'$feedFkey\PDO::PARAM_INT);
  575.         $stmt->bindValue(':active'$active\PDO::PARAM_INT);
  576.         $stmt->execute();
  577.     }
  578.     /** Add generic feed to client
  579.      *
  580.      * @param Request $request
  581.      * @param $clientKey
  582.      */
  583.     public function addGenericFeedToClient(Request $request$clientKey)
  584.     {
  585.         $genericClientKey $this->getGenericClientKey();
  586.         $genericFeedFkeys $request->request->get("generic_feed_fkey", array());
  587.         $pitFeedFkeys = isset($genericFeedFkeys['pit'])? array_values($genericFeedFkeys['pit']): array();
  588.         $nonPitFeedFkeys = isset($genericFeedFkeys['non_pit'])? array_values($genericFeedFkeys['non_pit']): array();
  589.         $formattedFeedFkeys = array();
  590.         foreach($pitFeedFkeys as $pitFeedFkey){
  591.             $formattedFeedFkeys[$pitFeedFkey] = 1;
  592.         }
  593.         foreach($nonPitFeedFkeys as $nonPitFeedFkey){
  594.             $formattedFeedFkeys[$nonPitFeedFkey] = 0;
  595.         }
  596.         $hasAccessToISIN $this->hasAccessToISIN($clientKey);
  597.         $feedAdded = array();
  598.         foreach($formattedFeedFkeys as $genericFeedFkey => $pit) {
  599.             $sql "SELECT feed_number
  600.                     FROM feeds.FEED
  601.                     WHERE feed_key = :generic_feed_fkey";
  602.             $db $this->getDoctrine()->getConnection();
  603.             $stmt $db->prepare($sql);
  604.             $stmt->bindValue(':generic_feed_fkey'$genericFeedFkey\PDO::PARAM_INT);
  605.             $stmt->execute();
  606.             $feedNumber = (int)$stmt->fetchColumn();
  607.             //check if generic PIT feed has normalized column to prevent adding it to client feed if missing
  608.             $sql ="SELECT COUNT(*)
  609.                      FROM feeds.FEED_FILE AS FF
  610.                      JOIN feeds.FEED_FILE_COLUMN AS FFC ON FF.feed_file_key = FFC.feed_file_fkey
  611.                     WHERE FF.feed_fkey = :feed_key AND FF.is_support_file = 0 AND FFC.is_normalized = 1";
  612.             $db $this->getDoctrine()->getConnection();
  613.             $stmt $db->prepare($sql);
  614.             $stmt->bindValue(":feed_key"$genericFeedFkey\PDO::PARAM_INT);
  615.             $stmt->execute();
  616.             $hasNormalizedColumn $stmt->fetchColumn();
  617.             if (!$hasNormalizedColumn && $pit){
  618.                 $this->addFlash('error'"GENERIC PIT feed $feedNumber missing normalized columns! Please fix the GENERIC feed first!");
  619.             } else {
  620.             $sql "SELECT COUNT(*)
  621.                     FROM feeds.CLIENT_TO_FEED AS CTF
  622.                     JOIN feeds.FEED AS F
  623.                       ON CTF.feed_fkey = F.feed_key
  624.                     WHERE F.feed_number = :feed_number
  625.                      AND CTF.client_fkey = :client_fkey";
  626.             $db $this->getDoctrine()->getConnection();
  627.             $stmt $db->prepare($sql);
  628.             $stmt->bindValue(':feed_number'$feedNumber\PDO::PARAM_INT);
  629.             $stmt->bindValue(':client_fkey'$clientKey\PDO::PARAM_INT);
  630.             $stmt->execute();
  631.             $count $stmt->fetchColumn();
  632.             if (!$count) {
  633.                 $sql "INSERT INTO feeds.FEED (feed_number, is_normalized, has_financial_block, meta_date_time_created)
  634.                         SELECT F.feed_number, :is_normalized , F.has_financial_block, NOW()
  635.                         FROM feeds.FEED AS F
  636.                         WHERE F.feed_key = :generic_feed_fkey
  637.                         LIMIT 1";
  638.                 $db $this->getDoctrine()->getConnection();
  639.                 $stmt $db->prepare($sql);
  640.                 $stmt->bindValue(':is_normalized'$pit\PDO::PARAM_INT);
  641.                 $stmt->bindValue(':generic_feed_fkey'$genericFeedFkey\PDO::PARAM_INT);
  642.                 $stmt->execute();
  643.                 $newFeedFkey $db->lastInsertId();
  644.                 if (!$newFeedFkey) {
  645.                     continue;
  646.                 }
  647.                 $sql "INSERT INTO feeds.CLIENT_TO_FEED (
  648.                             client_fkey,
  649.                             feed_fkey,
  650.                             is_active,
  651.                             is_normalized,
  652.                             meta_date_time_created)
  653.                         SELECT
  654.                            :client_fkey,
  655.                            :new_feed_fkey,
  656.                            is_active,
  657.                            :is_normalized,
  658.                            NOW()
  659.                         FROM feeds.CLIENT_TO_FEED
  660.                         WHERE feed_fkey = :generic_feed_fkey
  661.                           AND client_fkey = :generic_client_fkey
  662.                         LIMIT 1";
  663.                 $db $this->getDoctrine()->getConnection();
  664.                 $stmt $db->prepare($sql);
  665.                 $stmt->bindValue(':client_fkey'$clientKey\PDO::PARAM_INT);
  666.                 $stmt->bindValue(':new_feed_fkey'$newFeedFkey\PDO::PARAM_INT);
  667.                 $stmt->bindValue(':is_normalized'$pit\PDO::PARAM_INT);
  668.                 $stmt->bindValue(':generic_feed_fkey'$genericFeedFkey\PDO::PARAM_INT);
  669.                 $stmt->bindValue(":generic_client_fkey"$genericClientKey\PDO::PARAM_INT);
  670.                 $stmt->execute();
  671.                 $excludeTables '';
  672.                 if (!$pit) { // for non-pit, we need to exclude PUBLISHED and FB tables
  673.                     $excludeTables .= "AND table_name NOT LIKE '%\_PUBLISHED' AND table_name NOT LIKE '%\_FINANCIAL_BLOCK'";
  674.                 }
  675.                 //Don't add ISIN/CUSIP support tables if client doesnt have access
  676.                 //skip DNB table by default as its only for certain clients
  677.                 if (!$hasAccessToISIN) {
  678.                     $excludeTables .= "AND table_name NOT LIKE '%ISIN%' AND table_name NOT LIKE '%CUSIP%' AND table_name NOT LIKE '%DNB%'";
  679.                 }
  680.                 //Make a copy of feed files from GENERIC
  681.                 $sql "SELECT feed_file_key
  682.                         FROM feeds.FEED_FILE
  683.                         WHERE feed_fkey = :generic_feed_fkey
  684.                         {$excludeTables}";
  685.                 $db $this->getDoctrine()->getConnection();
  686.                 $stmt $db->prepare($sql);
  687.                 $stmt->bindValue(':generic_feed_fkey'$genericFeedFkey\PDO::PARAM_INT);
  688.                 $stmt->execute();
  689.                 $genericfeedFileKeys $stmt->fetchAll(\PDO::FETCH_COLUMN);
  690.                 $sql "SELECT name
  691.                         FROM feeds.CLIENT
  692.                         WHERE client_key = :client_key";
  693.                 $db $this->getDoctrine()->getConnection();
  694.                 $stmt $db->prepare($sql);
  695.                 $stmt->bindValue(":client_key"$clientKey\PDO::PARAM_INT);
  696.                 $stmt->execute();
  697.                 $clientName $stmt->fetchColumn();
  698.                 //remove generic name on client's feed file
  699.                 $feedNumber = ($feedNumber 10)? '0'$feedNumber $feedNumber;
  700.                 $feedFileName 'feed'$feedNumber '_' strtolower($clientName);
  701.                 // Only include feed files keys if their corresponding feed has at least one normalized column
  702.                 if ($pit) {
  703.                     // COUNT combined with GROUP BY will only return rows where the count of rows
  704.                     // marked as normalized is greater than 0
  705.                     $sql "SELECT COUNT(*), feed_file_fkey
  706.                             FROM feeds.FEED_FILE_COLUMN
  707.                             WHERE feed_file_fkey IN (?)
  708.                             AND is_normalized = 1
  709.                             GROUP BY feed_file_fkey";
  710.                     $db $this->getDoctrine()->getConnection();
  711.                     $stmt $db->executeQuery($sql, array($genericfeedFileKeys), array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY));
  712.                     $genericfeedFileKeys $stmt->fetchAll(\PDO::FETCH_COLUMN1);
  713.                 }
  714.                 foreach ($genericfeedFileKeys as $genericfeedFileKey) {
  715.                     $sql "INSERT INTO feeds.FEED_FILE (
  716.                                 feed_fkey,
  717.                                 database_name,
  718.                                 source_database_name,
  719.                                 table_name,
  720.                                 file_name,
  721.                                 is_support_file,
  722.                                 meta_date_time_created)
  723.                             SELECT
  724.                                 :new_feed_fkey,
  725.                                 database_name,
  726.                                 source_database_name,
  727.                                 table_name,
  728.                                 CASE WHEN is_support_file = 1 THEN file_name ELSE :feed_file_name END AS file_name,
  729.                                 is_support_file,
  730.                                 NOW()
  731.                             FROM feeds.FEED_FILE
  732.                             WHERE feed_file_key = :generic_feed_file_key
  733.                             LIMIT 1";
  734.                     $db $this->getDoctrine()->getConnection();
  735.                     $stmt $db->prepare($sql);
  736.                     $stmt->bindValue(':new_feed_fkey'$newFeedFkey\PDO::PARAM_INT);
  737.                     $stmt->bindValue(':generic_feed_file_key'$genericfeedFileKey\PDO::PARAM_INT);
  738.                     $stmt->bindValue(':feed_file_name'$feedFileName\PDO::PARAM_STR);
  739.                     $stmt->execute();
  740.                     $newFeedFileKey $db->lastInsertId();
  741.                     if (!$newFeedFileKey) {
  742.                         continue;
  743.                     }
  744.                     $sqlWhere '';
  745.                     if ($pit){ //For PIT, copy normalized columns from GENERIC
  746.                         $sqlWhere "AND FFC.is_normalized = 1 ";
  747.                     }
  748.                     if (!$hasAccessToISIN) {
  749.                         $sqlWhere .= " AND C.select_column NOT IN ('isin', 'cusip_number')";
  750.                     }
  751.                     $sql "INSERT INTO feeds.FEED_FILE_COLUMN (
  752.                                 feed_file_fkey,
  753.                                 column_fkey,
  754.                                 is_primary_key,
  755.                                 is_business_key,
  756.                                 is_proprietary_column,
  757.                                 is_foreign_key,
  758.                                 is_normalized,
  759.                                 is_active,
  760.                                 is_event_date,
  761.                                 is_company_block,
  762.                                 is_financial_block,
  763.                                 is_eol,
  764.                                 has_delta,
  765.                                 select_order,
  766.                                 meta_date_time_created)
  767.                             SELECT
  768.                                 :new_feed_file_fkey,
  769.                                 FFC.column_fkey, 
  770.                                 FFC.is_primary_key, 
  771.                                 FFC.is_business_key, 
  772.                                 FFC.is_proprietary_column, 
  773.                                 FFC.is_foreign_key, 
  774.                                 FFC.is_normalized,
  775.                                 FFC.is_active,
  776.                                 FFC.is_event_date,
  777.                                 FFC.is_company_block,
  778.                                 FFC.is_financial_block,
  779.                                 FFC.is_eol,
  780.                                 FFC.has_delta,                                
  781.                                 FFC.select_order, 
  782.                                 NOW()
  783.                             FROM feeds.FEED_FILE_COLUMN AS FFC
  784.                             JOIN feeds.FEED_FILE AS FF
  785.                               ON FF.feed_file_key = FFC.feed_file_fkey
  786.                             JOIN feeds.FEED_COLUMN AS C 
  787.                               ON FFC.column_fkey = C.column_key  
  788.                             WHERE FFC.feed_file_fkey = :generic_feed_file_fkey
  789.                                 AND FFC.is_eol != 1
  790.                              AND C.select_column NOT LIKE 'meta%'
  791.                              {$sqlWhere}";
  792.                     $db $this->getDoctrine()->getConnection();
  793.                     $stmt $db->prepare($sql);
  794.                     $stmt->bindValue(':new_feed_file_fkey'$newFeedFileKey\PDO::PARAM_INT);
  795.                     $stmt->bindValue(':generic_feed_file_fkey'$genericfeedFileKey\PDO::PARAM_INT);
  796.                     $stmt->execute();
  797.                 }
  798.                 $feedAdded[] = $feedNumber;
  799.             }
  800.           }
  801.         }
  802.         if ($feedAdded) {
  803.             $feedAddedString implode(', '$feedAdded);
  804.             $this->addFlash('success'"GENERIC feeds $feedAddedString added to this client!");
  805.         }
  806.         return $this->redirectToRoute('client_view', array('clientKey' => $clientKey));
  807.     }
  808.     /**
  809.      * @param Request $request
  810.      * @return \Symfony\Component\HttpFoundation\Response
  811.      */
  812.     public function searchClientFeed(Request $request){
  813.         $searchBy $request->query->get('search_by');
  814.         $searchTerm $request->query->get('search_term');
  815.         $searchResult = array();
  816.         if ($searchTerm) {
  817.             if ($searchBy == 'feed') {
  818.                 $sql "SELECT 
  819.                            C.client_key,
  820.                            C.name, 
  821.                            C.is_active,
  822.                            F.feed_number,
  823.                            F.feed_key,
  824.                            CA.client_account_key,
  825.                            CA.account_name,
  826.                            CA.contact,
  827.                            CTF.is_active AS feed_active
  828.                         FROM feeds.FEED AS F
  829.                         JOIN feeds.CLIENT_TO_FEED AS CTF ON CTF.feed_fkey = F.feed_key
  830.                         JOIN feeds.CLIENT AS C ON CTF.client_fkey = C.client_key
  831.                         LEFT JOIN feeds.CLIENT_ACCOUNT AS CA ON C.name = CA.client_name
  832.                         WHERE F.feed_number = :feed_number 
  833.                         ORDER BY C.is_active DESC, CTF.is_active DESC, C.name, F.feed_number";
  834.                 $db $this->getDoctrine()->getConnection();
  835.                 $stmt $db->prepare($sql);
  836.                 $stmt->bindValue(':feed_number'$searchTerm\PDO::PARAM_INT);
  837.                 $stmt->execute();
  838.             } elseif ($searchBy == 'column') {
  839.                 $sql "SELECT 
  840.                            C.client_key,
  841.                            C.name, 
  842.                            C.is_active,
  843.                            F.feed_number,
  844.                            F.feed_key,
  845.                            CA.client_account_key,
  846.                            CA.account_name,
  847.                            CA.contact,
  848.                            CTF.is_active AS feed_active
  849.                         FROM feeds.FEED AS F
  850.                         JOIN feeds.FEED_FILE AS FF ON F.feed_key = FF.feed_fkey
  851.                         JOIN feeds.FEED_FILE_COLUMN AS FFC ON FF.feed_file_key = FFC.feed_file_fkey
  852.                         JOIN feeds.FEED_COLUMN AS FC ON FFC.column_fkey = FC.column_key  
  853.                         JOIN feeds.CLIENT_TO_FEED AS CTF ON CTF.feed_fkey = F.feed_key
  854.                         JOIN feeds.CLIENT AS C ON CTF.client_fkey = C.client_key
  855.                         LEFT JOIN feeds.CLIENT_ACCOUNT AS CA ON C.name = CA.client_name
  856.                         WHERE FC.select_column LIKE :select_column 
  857.                         ORDER BY C.is_active DESC, CTF.is_active DESC, C.name, F.feed_number";
  858.                 $db $this->getDoctrine()->getConnection();
  859.                 $stmt $db->prepare($sql);
  860.                 $stmt->bindValue(':select_column'$searchTerm\PDO::PARAM_STR);
  861.                 $stmt->execute();
  862.             }
  863.             while ($row $stmt->fetch(\PDO::FETCH_ASSOC)) {
  864.                 $clientKey $row['client_key'];
  865.                 $accountKey $row['client_account_key'];
  866.                 $feedKey $row['feed_key'];
  867.                 $searchResult[$clientKey]['client_key'] = $clientKey;
  868.                 $searchResult[$clientKey]['is_active'] = $row['is_active'];
  869.                 $searchResult[$clientKey]['name'] = $row['name'];
  870.                 $searchResult[$clientKey]['feeds'][$feedKey] =  array(
  871.                     'feed_key' => $feedKey,
  872.                     'feed_number' => $row['feed_number'],
  873.                     'feed_active' => $row['feed_active'],
  874.                 );
  875.                 $searchResult[$clientKey]['accounts'][$accountKey] = array(
  876.                     'account_name' => $row['account_name'],
  877.                     'contact' => $row['contact'],
  878.                 );
  879.             }
  880.         }
  881.         $data = array(
  882.             'search_by' => $searchBy,
  883.             'search_term' => $searchTerm,
  884.             'search_result' => $searchResult
  885.         );
  886.         return $this->render('client/search.html.twig'$data);
  887.     }
  888. }