ACC SHELL
<?php
/**
* Subsites
*
* @author Melounek, Vlahovic
*/
class Sites_model extends Relations_model {
public $table = "sites";
public $lang = "cz";
public $zero_sitemap=true;// z drobeckovky vyhodi polozky, ktere maji hodnotu ve sloupci sitemap 0
public function __construct(){
parent::__construct();
$this->root_relation = Settings_model::$root_relation;
// useful columns are closely connected with set_joins()
$this->set_useful_columns(array('t_parts.content as title','published_at','tags'));
$this->set_joins("left join sites_parts t_parts on t_parts.part='title' && t_parts.lang='".$this->lang."' && t_parts.id_sites = sites.id");
//$this->repair_tree();
}
/**
* docs in Base_model()
*/
public function new_one($data=NULL,$call_get_one=false){
$result = parent::new_one($data,$call_get_one);
$result->lang = $this->lang;
return $result;
}
/**
* @param type $idr id of relation to this site
* @return object $this
*/
public function get_one($idr=NULL){
$this->load(NULL,NULL,$idr);
$sql = " # get one site
select *,sites.id as id, relations.id as idr
from sites" . $this->left_join() ."
join relations on relations.id_sites=sites.id
left join sites_access on sites_access.id_site=sites.id
where relations.id='". $this->idr ."'
order by relations.id #take first relation
limit 1";
$data = $this->db->query($sql)->row_array();
if(empty($data)){
Tools::critical("sites_model::get_one() returned no data on object: ".var_export($this,1));
}else{
$data['tags'] = trim(str_replace("##"," ",$data['tags']),"#");
foreach(explode("##",trim($data['tags'])) as $e){
$data['tags_enum'][$e] = true;
}
$this->load($data);
Tools::log("sites_model::get_one() set data of site with id=".$this->id." idr=".$this->idr);
$this->files();
$this->parts();
}
return $this;
}
public function search($q,$call_get_one=null){
$this->db->query('SET SESSION group_concat_max_len = 10000000');
$search = $this->sites->new_one();
$search->set_joins("join sites_parts s_parts on s_parts.id_sites=sites.id");
$search->set_where("relations.table='sites'
group by sites.id,idr
# search pattern
having group_concat(s_parts.content) like '%$q%'");
return $search->get_all($call_get_one);
}
public function get_all($call_get_one=false,$log_msg=false){
$rel = $this->get_relation($this->root_relation['id'], false, false);
parent::set_where($this->where . ($this->where?" && ":"") . "lft>='".$rel['lft']."' && rgt<='".$rel['rgt']."'");
return parent::get_all($call_get_one,$log_msg);
}
/**
* Returns object of this tag taken from $this->idr or if not set from $this->root_relation
* @param string $tag
* @return object of this tag
*/
public function tag($tag,$idr=NULL){
$tags = $this->tags($tag,$idr);
$count = count($tags);
if($count>1){
Tools::critical("tag() found more than one result! ".var_export($tags,1));
return $this;
}elseif($count==0){
Tools::debug("tag('".$tag."') not found!");
$this->idr = $this->id = $this->a = false;
return $this;
}else{
return $this->load($tags[0]);
}
}
// returns array with idrs and ids of this tag
public function tags($tag,$idr=NULL){
if($idr){
$this->idr = $idr;
}else{
$this->idr = $this->root_relation['id'];
}
$rel = $this->get_relation($this->idr, false, false);
$sql = " # load all relations by site tags
select sites.id as id, relations.id as idr
from sites join relations on id_sites=sites.id
where sites.tags like '%#".$tag."#%'
&& lft>='".$rel['lft']."' && rgt<='".$rel['rgt']."'";
return $this->db->query($sql)->result_array();
}
/**
* Returns count of finded matches of this tag in specified context
* @param string $tag
* @param bool $inherit 1 = search in parents too
* @param int $offset default is 0 = self and ancessories, 1 ancessories ....
* @param int $range range of ancessories. Default is all (0). 1 = only this offset ...
* @return int count of matches
*/
public function has_tag($tag,$inherit=false,$offset=0,$range=0){
$obj = $this->new_one();
$obj->idr = $this->idr;
if(empty($this->idr)){
if(!empty($this->a['parent_id']) && $inherit){ // if idr not specified but parent_id is, use it
$obj->idr = $this->a['parent_id'];
if($offset) $offset--;
}else{
Tools::debug("has_tag($tag,$inherit,$offset,$range) called on object without idr. If its new object, its ok ");
return false;
}
}
$rel = $obj->get_relation();
$where="tags like '%#$tag#%'";
if($inherit){
$where .= "&& lft<=".$rel['lft']." && rgt>=".$rel['rgt'];
if($offset) $where .= "&& depth<=".($rel['depth']-$offset); // how far from this node
if($range) $where .= "&& depth>".($rel['depth']-$offset-$range); // how maximal from offset
}else{
$where .= "&& relations.id = $obj->idr";
}
$obj->set_where($where);
$result = $obj->get_all(false,false);
Tools::log("Sites_model::has_tag('$tag') returned ".count($result)." matches");
return count($result);
}
/**
* Returns url of this site
* @return string
*/
public function url(){
return $this->uri->sef_site($this->idr);
}
/**
* Returns complete link of this site
* example: <a href="/foo">foo</a>
* @return string
*/
public function link(){
return '<a href="' . $this->uri->sef_site($this->idr) . '">' . $this->part("title") . '</a>';
}
// mělo by mít také $inherit jako parametr
public function part($part,$inherit=false,$id=null){
if(isset($this->a['parts'][$part]) && $this->a['parts'][$part] !== true) return $this->a['parts'][$part];
if(!$id) $id = $this->id;
$result = $this->db->query(" # take parts of site
select content from sites_parts WHERE id_sites='".$id."' && part='".$part."'")->row_array();
if($inherit && empty($result)){
$rel = $this->get_relation_by_site($id);
if(!empty($rel['parent_id'])){
$parent = $this->sites->new_one($rel)->parent();
if(!empty($parent->id)){ // recursive
return $this->part($part,1,$parent->id);
}
}
}
if(empty($result['content'])){
Tools::log("part('$part','$inherit') not found anything");
return false;
}
return $result['content'];
}
// zároveň přeparsuje obrázky
public function parsed_part($part,$inherit=false,$id=null){
$this->benchmark->mark('t1');
$parsed_part = $this->data['img']->parse($this->part($part,$inherit,$id));
$this->benchmark->mark('t2');
Tools::debug("sites_model() prints parsed_part($part,$inherit,$id) in time ".$this->benchmark->elapsed_time('t1','t2'));
return $parsed_part;
}
public function parts($id=null){
if(!$id) $id = $this->id;
if($id == $this->id && !empty($this->a['parts'])) return $this->a['parts'];
$res = $this->db->query(" #take parts of site
select * from sites_parts WHERE id_sites='".$id."'")->result_array();
$this->a['parts'] = array();
foreach($res as $r){
$this->a['parts'][$r['part']] = $r['content'];
}
//Tools::log("sites_model::parts() set \$this->a[parts] as: ".var_export(@$this->a['parts'],1)); // too much results
return $this->a['parts'];
}
/////// SPECIAL PARTS ////////
public function part_h1_title(){
$this->parts();
if($this->part('h1_title')) return $this->part('meta_title');
return $this->part('title');
}
public function part_meta_title(){
$this->parts();
if($this->part('meta_title')) return $this->part('meta_title');
return $this->part('title');
}
/**
* @param string $prefered_part part from where it trying to get description
*/
public function part_meta_description($prefered_part=""){
$this->parts();
if($this->part('meta_description')) return $this->part('meta_description');
if($prefered_part && $this->part($prefered_part)) return Tools::truncate($this->part($p),150);
if($this->part('text')) return Tools::truncate($this->part('text'),150);
$max_length = 0; $max_index = 0;
foreach($this->a['parts'] as $i=>$p) if(strlen($p)>$max_length) $max_index = $i;
return Tools::truncate($this->a['parts'][$max_index],150); // takes longest part
}
public function part_meta_keywords(){
$this->parts();
if($this->part('meta_keywords',1)) return $this->part('meta_keywords',1);
Tools::debug("sites_model::part_meta_keywords() returned nothing");
}
////////////////////////////////////
/**
* get all files and order it into $this->a['images'] and $this->a['docs']
*
* @param type $id_sites
* @return type
*/
public function files($id_sites=null){
if(!$id_sites) $id_sites = $this->id;
$sql = " # file select
select *, file_url as url, concat('<a href=\"',file_url,'\">',file,'</a>') as link
from files where id_sites='".$id_sites."'
order by list";
$this->a['files'] = $this->db->query($sql)->result_array();
$this->a['images'] = array();
$this->a['docs'] = array();
foreach($this->a['files'] as $f){
if(stripos($f['file_url'],".jpg") || stripos($f['file_url'],".png") || stripos($f['file_url'],".gif")){
$this->a['images'][] = $f;
}else{
$this->a['docs'][] = $f;
}
}
return $this->a['files'];
}
/**
* Deletes only one site with this id
* @param int $id if NULL, select from $this->id
* @return bool
*/
public function del_sites($id=NULL){ // smaže stránky a děti
$this->load(NULL,$id);
Tools::debug("delete site id=$this->id");
$instance =& get_instance();
$instance->load->model("files_model");
foreach($this->files() as $f){
$instance->files_model->del_files($f['id']);
}
$this->db->query('delete from sites_parts where id_sites="'.$this->id.'"');
$this->db->query('delete from sites where id="'.$this->id.'"');
return true;
}
/**
* save site files and parts
*
* @param array $data [optional]
* @param integer $id [optional]
* @param integer $idr [optional]
* @return boolean
*/
public function save_site($data=NULL,$id=NULL,$idr=NULL){
$data['tags'] = "#" . str_replace(" ","##",trim($data['tags'])) . "#";
$data['sitemap']=(!empty($data['sitemap']) ? 1 : 0);
if(empty($data['published_at']) || strpos($data['published_at'],"0000")!==false){
$data['published_at'] = date("Y-m-d H:i");
}
$this->load($data,$id,$idr);
// var_dump($data);
// exit('<br>'.__FILE__.'; '.__LINE__);
if(empty($this->a['parent_id']) && empty($this->id)){
die("pruser");
}
if(($return = $this->save())){
if(!empty($this->a['parent_id'])){
if(!$this->save_relation()){
Tools::critical("nepovedlo se ulozit relaci pro id_sites='$this->id'");
return false;
}
}
// save parts
if(!empty($this->a['parts'])){
foreach($this->a['parts'] as $part=>$content){
$content = str_replace(array("'",'"'),array("\\'",'\\"'),$content);
$this->db->query("delete from sites_parts where part='".$part."' && id_sites='".$this->id."'");
if($content) $this->db->query("insert into sites_parts (content,part,id_sites) values ('".$content."','".$part."','".$this->id."')");
}
}
require_once("models/files_model.php");
$this->files = new Files_model();
//save files
if(!empty($_POST['files'])){
foreach($_POST['files'] as $id=>$file){
$this->files->save_file($file);
}
}
//new files
if(!empty($_FILES['new_files'])){
$files = $_FILES['new_files'];
foreach($files['name'] as $ind=>$f){
if(empty($files['tmp_name'][$ind])) continue;
$file = array(
'uploaded_file' => array("name"=>$f,"tmp_name"=>$files['tmp_name'][$ind],"type"=>$files['type'][$ind]),
'file_url' => $f,
'id_sites' => $this->id
);
$this->files->id = NULL;
$this->files->save_file($file);
}
}
//save url
if($this->has_tag("hp")){
$this->uri->save_sef("home/site/".$this->idr,"",$this->idr); // save homepage
}elseif($this->has_tag("error_404")){
$this->uri->save_sef("home/site/".$this->idr,"error-404",$this->idr); // save homepage
}else{
$url_str = $this->part('meta_title')?$this->part('meta_title'):$this->part('title');
$this->uri->save_sef("home/site/".$this->idr,$url_str,$this->idr);
}
Tools::debug("site id=$this->id idr=$this->idr was saved");
}else{
Tools::critical ("Nelze vložit data, Admin::sites().");
}
return $return;
}
/**
* podedi stav vsem potomkum
*
* @param integer $idr root od ktereho se ma dedit
* @return mixed v pripade uspechu pocet zmenych zaznamu (vcetne 0), jinak false
*/
public final function state_inherit($idr){
$return=false;
if($idr){
$parent = $this->get_relation($idr,false,false);
// nastavi mysql promennou s id stavu, protoze v update se nemuzu ptat na updatovanou tabulku
$query='SELECT @parent_id_sites_state:=(SELECT id_sites_states FROM sites WHERE id='.$parent['id_sites'].' LIMIT 1);';
if($this->db->query($query)){
$query="UPDATE sites SET id_sites_states=@parent_id_sites_state WHERE id IN (SELECT id_sites FROM relations WHERE lft>".$parent['lft']." AND rgt<".$parent['rgt'].")";
if($this->db->query($query)){
$return=mysql_affected_rows();
}
}
}
return $return;
}
/**
* vrati id stavu podedeneho od nektereho z predku
*
* @param integer $idr idr uzlu od ktereho se ma hledat (vcetne)
* @return mixed pokud najde pak integer, jinak null
*/
public final function inherited_state($idr){
$return=null;
$idr=intval($idr);
if($idr){
// nastavim si mysql promenne rootu
$query="
# nastaveni promennych pro zjisteni dedicnych stavu predku
SELECT @var_lft:=lft, @var_rgt:=rgt FROM relations WHERE id=".$idr;
$this->db->query($query);
// vytahnu info o prvnim predkovi s nastavenou dedicnosti
$query="
# dedicna infomace predka - genetika...
SELECT s.id_sites_states FROM relations AS r LEFT JOIN sites AS s ON s.id=r.id_sites WHERE r.lft<=@var_lft AND r.rgt>=@var_rgt AND s.state_inherit=1 ORDER BY r.depth DESC LIMIT 1";
$return=@$this->db->query($query)->row()->id_sites_states;
}
else{
Tools::flash('No IDR at '.__FILE__.' (line: '.__LINE__.')!', 'warn');
}
return $return;
}
}
ACC SHELL 2018